]>
Commit | Line | Data |
---|---|---|
3b542afc MG |
1 | `include "news.v" |
2 | ||
5a2a82dc MG |
3 | `define OP_NOP 3'd0 |
4 | `define OP_LOADA 3'd1 | |
5 | `define OP_LOADB 3'd2 | |
6 | `define OP_STORE 3'd3 | |
7 | `define OP_READ 3'd4 | |
8 | `define OP_LOADI 3'd5 | |
9 | `define OP_ROUTE 3'd6 | |
10 | `define OP_RUG 3'd7 | |
11 | ||
23c26e04 MG |
12 | `define DIRECTION_N 3'd0 |
13 | `define DIRECTION_NE 3'd1 | |
14 | `define DIRECTION_E 3'd2 | |
15 | `define DIRECTION_SE 3'd3 | |
16 | `define DIRECTION_S 3'd4 | |
17 | `define DIRECTION_SW 3'd5 | |
18 | `define DIRECTION_W 3'd6 | |
19 | `define DIRECTION_NW 3'd7 | |
20 | ||
3b542afc | 21 | module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, output reg [63:0] mem_in, input [63:0] mem_out, output reg mem_write); |
5a2a82dc MG |
22 | |
23 | // parity is unimplemented | |
24 | ||
25 | // OP_LOADA | |
23c26e04 MG |
26 | wire [3:0] flagr = I[3:0]; |
27 | wire bsel = I[4]; | |
28 | wire [0:7] aluc = I[12:5]; | |
5a2a82dc MG |
29 | |
30 | // OP_LOADB | |
23c26e04 MG |
31 | wire [3:0] cond = I[3:0]; |
32 | wire inv = I[4]; | |
33 | wire [0:7] alus = I[12:5]; | |
5a2a82dc MG |
34 | |
35 | // OP_STORE | |
23c26e04 | 36 | wire [3:0] flagw = I[3:0]; |
5a2a82dc MG |
37 | wire edge_ = I[7]; |
38 | wire [3:0] cube = I[11:8]; | |
39 | ||
40 | // OP_ROUTE | |
41 | wire [5:0] cycle = I[5:0]; | |
42 | wire [1:0] check = I[7:6]; | |
43 | wire [3:0] xor_ = I[11:8]; | |
44 | wire [2:0] snarf = I[14:12]; | |
45 | wire odd = I[15]; | |
46 | ||
47 | // OP_RUG | |
48 | wire rw = I[0]; | |
49 | wire ac = I[1]; | |
50 | wire news = I[2]; | |
51 | wire [4:0] reg_ = I[8:4]; | |
52 | ||
53 | ||
3b542afc MG |
54 | reg [63:0] A = 0; |
55 | reg [63:0] B = 0; | |
56 | reg [63:0] C = 0; | |
57 | reg [63:0] F = 0; | |
58 | reg [63:0] Cond = 0; | |
59 | reg [63:0] R = 0; | |
23c26e04 MG |
60 | reg [7:0] alu_sum = 0; |
61 | reg [7:0] alu_carry = 0; | |
3b542afc | 62 | reg [63:0] cube_in; |
5a2a82dc MG |
63 | reg io; |
64 | ||
65 | // these are not really regs | |
66 | ||
3b542afc MG |
67 | reg [63:0] alu_sum_out; |
68 | reg [63:0] alu_carry_out; | |
23c26e04 | 69 | |
3b542afc | 70 | reg [2:0] alu_index [63:0]; |
23c26e04 MG |
71 | |
72 | reg [15:0] idx; | |
5a2a82dc MG |
73 | |
74 | always @* begin | |
3b542afc | 75 | for(idx = 0; idx < 64; idx=idx+1) begin |
23c26e04 MG |
76 | alu_index[idx] = (A[idx] << 2) + (B[idx] << 1) + F[idx]; |
77 | alu_sum_out[idx] <= alu_sum[alu_index[idx]]; | |
78 | alu_carry_out[idx] <= alu_carry[alu_index[idx]]; | |
79 | end | |
5a2a82dc MG |
80 | end |
81 | ||
23c26e04 MG |
82 | reg [3:0] flags_addr_latch; |
83 | reg [3:0] flags_addr; | |
84 | ||
85 | always @* begin | |
86 | if(flags_addr_latch) | |
87 | flags_addr <= flags_addr_latch; | |
88 | else | |
89 | case(op) | |
90 | `OP_LOADA: | |
91 | flags_addr <= flagr; | |
92 | `OP_LOADB: | |
93 | flags_addr <= cond; | |
94 | `OP_STORE: | |
95 | flags_addr <= flagw; | |
96 | default: | |
97 | flags_addr <= 0; | |
98 | endcase | |
99 | end // always @ * | |
100 | ||
3b542afc MG |
101 | reg [63:0] flags_in; |
102 | wire [63:0] flags_out; | |
5a2a82dc MG |
103 | reg flags_write; |
104 | ||
3b542afc | 105 | reg [63:0] latest_news; |
5a2a82dc | 106 | |
23c26e04 MG |
107 | RAM #(.ADDRESS_BITS(3)) flags (.clk(clk), .write(flags_write), .addr(flags_addr[2:0]), .in(flags_in), .out(flags_out)); |
108 | ||
3b542afc MG |
109 | reg [63:0] flag_or_news; |
110 | reg [63:0] news_out; | |
23c26e04 | 111 | |
3b542afc | 112 | news newspaper (.news_in(latest_news), .direction(flags_addr[1:0]), .news_out(news_out)); |
23c26e04 | 113 | |
3b542afc | 114 | assign flag_or_news = flags_addr[3] ? news_out : flags_out; |
5a2a82dc MG |
115 | |
116 | always @ (posedge clk) begin | |
117 | if(mem_write) | |
118 | mem_write <= 0; | |
23c26e04 MG |
119 | if(flags_write) begin |
120 | flags_write <= 0; | |
121 | flags_addr_latch <= 0; | |
122 | end | |
5a2a82dc MG |
123 | |
124 | case (op) | |
125 | `OP_NOP: begin end | |
126 | ||
127 | `OP_LOADA: | |
128 | begin | |
129 | alu_carry <= aluc; | |
23c26e04 | 130 | F <= flag_or_news; |
5a2a82dc MG |
131 | A <= mem_out; |
132 | C <= mem_out; | |
133 | io <= io_pin; | |
134 | if (bsel) | |
135 | B <= cube_in; | |
136 | end | |
137 | ||
138 | `OP_LOADB: | |
139 | begin | |
140 | alu_sum <= alus; | |
23c26e04 | 141 | Cond <= inv ? ~flag_or_news : flag_or_news; |
5a2a82dc MG |
142 | B <= mem_out; |
143 | R <= mem_out; | |
144 | end | |
145 | ||
146 | `OP_STORE: | |
147 | begin | |
3b542afc | 148 | for(idx = 0; idx < 64; idx++) begin |
23c26e04 MG |
149 | flags_in[idx] = Cond[idx] ? alu_carry_out[idx] : flags_out[idx]; |
150 | latest_news[idx] <= flags_in[idx]; | |
151 | end | |
152 | if(flags_addr) begin // we do not write to flag 0 | |
153 | flags_write <= 1; | |
154 | flags_addr_latch <= flags_addr; | |
155 | end | |
5a2a82dc MG |
156 | mem_in <= alu_sum_out; |
157 | mem_write <= 1; | |
5a2a82dc MG |
158 | end |
159 | ||
160 | `OP_READ: | |
161 | begin | |
162 | if (CS) | |
163 | mem_in <= mem_out; | |
164 | end | |
165 | ||
166 | `OP_LOADI: | |
167 | begin | |
168 | C <= mem_out; | |
169 | A <= I; | |
170 | alu_sum <= 8'b11110000; // out of A, B, F, select exactly A | |
171 | end | |
172 | ||
173 | /* `OP_RUG: | |
174 | begin | |
175 | if(!rw && ac && !news) | |
176 | begin | |
177 | rug[reg_] <= A; | |
178 | C <= mem_out; | |
179 | end | |
180 | if(!rw && !ac && !news) | |
181 | begin | |
182 | rug[reg_] <= C; | |
183 | A <= mem_out; | |
184 | end | |
185 | if(rw && ac && !news) | |
186 | begin | |
187 | A <= rug[reg_]; | |
188 | mem_in <= C; | |
189 | end | |
190 | if(rw && !ac && !news) | |
191 | begin | |
192 | C <= rug[reg_]; | |
193 | mem_in <= A; | |
194 | end | |
195 | if(rw && !ac && news) | |
196 | begin | |
197 | R <= mem_out; | |
198 | cube_in <= mem_out; | |
199 | end | |
200 | if(rw && ac && news) | |
201 | begin | |
202 | cube_in <= mem_out; | |
203 | end | |
204 | end | |
205 | */ | |
206 | endcase | |
207 | end | |
208 | endmodule |