| 1 | `include "ram.v" |
| 2 | |
| 3 | `define STATE_INIT 3'd0 |
| 4 | `define STATE_READ_A 3'd1 |
| 5 | `define STATE_READ_B 3'd2 |
| 6 | `define STATE_WRITE 3'd3 |
| 7 | |
| 8 | `define FLAG_NEWS 4'd8 |
| 9 | `define FLAG_CUBE 4'd9 |
| 10 | `define FLAG_ROUTER 4'd10 |
| 11 | `define FLAG_ROUTER_ACK 4'd11 |
| 12 | `define FLAG_DAISY_CHAIN 4'd12 |
| 13 | `define FLAG_LONG_PARITY 4'd13 |
| 14 | `define FLAG_INPUT 4'd14 |
| 15 | `define FLAG_ZERO 4'd15 |
| 16 | |
| 17 | `define DIRECTION_N 3'd0 |
| 18 | `define DIRECTION_NE 3'd1 |
| 19 | `define DIRECTION_E 3'd2 |
| 20 | `define DIRECTION_SE 3'd3 |
| 21 | `define DIRECTION_S 3'd4 |
| 22 | `define DIRECTION_SW 3'd5 |
| 23 | `define DIRECTION_W 3'd6 |
| 24 | `define DIRECTION_NW 3'd7 |
| 25 | |
| 26 | module cpu |
| 27 | (input clk, input text[54:0], |
| 28 | input cube, input daisy_chain, input pin_input, input router_ack, |
| 29 | input [7:0] news_in, output [7:0] news_out, |
| 30 | output flag_out, output reg writing_to_router, |
| 31 | output mem_in, input mem_out |
| 32 | ); |
| 33 | |
| 34 | wire [3:0] read_flag = text[30:27]; |
| 35 | wire [3:0] write_flag = text[26:23]; |
| 36 | wire [3:0] condition_flag = text[22:19]; |
| 37 | wire condition_sense = text[18]; |
| 38 | wire [7:0] memory_truth_table = text[17:10]; |
| 39 | wire [7:0] flag_truth_table = text[9:2]; |
| 40 | wire [1:0] news_direction = text[1:0]; |
| 41 | |
| 42 | reg [7:0] general_flags; |
| 43 | reg news_flag; |
| 44 | wire [15:0] flags = {1'd0, pin_input, 1'd0, daisy_chain, router_ack, 1'd0, cube, news_flag, general_flags}; |
| 45 | |
| 46 | always @* begin |
| 47 | flags[7:0] = general_flags[7:0]; |
| 48 | case(news_direction) |
| 49 | `DIRECTION_NORTH: news_flag = north_in; |
| 50 | `DIRECTION_EAST: news_flag = east_in; |
| 51 | `DIRECTION_WEST: news_flag = west_in; |
| 52 | `DIRECTION_SOUTH: news_flag = south_in; |
| 53 | endcase // case (news_direction) |
| 54 | end |
| 55 | |
| 56 | reg alu_in_a; |
| 57 | reg alu_in_b; |
| 58 | reg alu_in_f; |
| 59 | |
| 60 | reg alu_index; |
| 61 | |
| 62 | reg alu_out_memory; |
| 63 | reg alu_out_flag; |
| 64 | |
| 65 | always @* begin |
| 66 | alu_in_f = flags[read_flag]; |
| 67 | alu_index = (alu_in_a << 2) + (alu_in_b << 1) + alu_in_f; |
| 68 | |
| 69 | alu_out_memory = memory_truth_table[alu_index]; |
| 70 | alu_out_flag = flag_truth_table[alu_index]; |
| 71 | end |
| 72 | |
| 73 | assign flag_out = alu_out_flag; |
| 74 | |
| 75 | reg [2:0] state = `STATE_INIT; |
| 76 | |
| 77 | always @ (posedge clk) begin |
| 78 | case (state) |
| 79 | `STATE_INIT: |
| 80 | begin |
| 81 | mem_addr <= address_a; |
| 82 | state <= `STATE_READ_A |
| 83 | end |
| 84 | |
| 85 | `STATE_READ_A: |
| 86 | begin |
| 87 | alu_in_a <= mem_out; |
| 88 | mem_addr <= address_b; |
| 89 | mem_write <= 0; |
| 90 | writing_to_router <= 0; |
| 91 | state <= `STATE_READ_B; |
| 92 | end |
| 93 | |
| 94 | `STATE_READ_B: |
| 95 | begin |
| 96 | alu_in_b <= mem_out; |
| 97 | mem_addr <= address_a; |
| 98 | state <= `STATE_WRITE; |
| 99 | end |
| 100 | |
| 101 | `STATE_WRITE: |
| 102 | begin |
| 103 | mem_in <= alu_out_memory; |
| 104 | mem_write <= 1; |
| 105 | state <= `STATE_READ_A; |
| 106 | |
| 107 | if(!write_flag[3]) |
| 108 | general_flags[write_flag[2:0]] <= alu_out_flag; |
| 109 | |
| 110 | if(write_flag == `FLAG_ROUTER_DATA) |
| 111 | writing_to_router <= 1; |
| 112 | end |
| 113 | endcase |
| 114 | end |
| 115 | |
| 116 | endmodule |