implement routing + storei instruction
[clump.git] / chip.v
CommitLineData
3b542afc
MG
1`include "news.v"
2
7f1b6bd9
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_STOREI 3'd4
8`define OP_LOADI 3'd5
9`define OP_ROUTE 3'd6
10`define OP_LED 3'd7
5a2a82dc 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
7f1b6bd9 21module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, output reg [15:0] mem_in, input [15:0] mem_out, output reg mem_write, output reg [3:0] led_out = 0);
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
7f1b6bd9
MG
53 // OP_LED
54 wire mode = I[4];
55 wire [1:0] offset = I[1:0];
56 wire [3:0] leds = I[3:0];
5a2a82dc 57
7f1b6bd9
MG
58
59 reg [15:0] A = 0;
60 reg [15:0] B = 0;
61 reg [15:0] C = 0;
62 reg [15:0] F = 0;
63 reg [15:0] Cond = 0;
64 reg [15:0] R = 0;
23c26e04
MG
65 reg [7:0] alu_sum = 0;
66 reg [7:0] alu_carry = 0;
7f1b6bd9 67 reg [15:0] cube_in;
5a2a82dc
MG
68 reg io;
69
70 // these are not really regs
71
7f1b6bd9
MG
72 reg [15:0] alu_sum_out;
73 reg [15:0] alu_carry_out;
23c26e04 74
7f1b6bd9 75 reg [2:0] alu_index [15:0];
23c26e04
MG
76
77 reg [15:0] idx;
5a2a82dc
MG
78
79 always @* begin
7f1b6bd9 80 for(idx = 0; idx < 16; idx=idx+1) begin
23c26e04
MG
81 alu_index[idx] = (A[idx] << 2) + (B[idx] << 1) + F[idx];
82 alu_sum_out[idx] <= alu_sum[alu_index[idx]];
83 alu_carry_out[idx] <= alu_carry[alu_index[idx]];
84 end
5a2a82dc
MG
85 end
86
23c26e04
MG
87 reg [3:0] flags_addr_latch;
88 reg [3:0] flags_addr;
89
90 always @* begin
91 if(flags_addr_latch)
92 flags_addr <= flags_addr_latch;
93 else
94 case(op)
95 `OP_LOADA:
96 flags_addr <= flagr;
97 `OP_LOADB:
98 flags_addr <= cond;
99 `OP_STORE:
100 flags_addr <= flagw;
101 default:
102 flags_addr <= 0;
103 endcase
104 end // always @ *
105
7f1b6bd9
MG
106 reg [15:0] flags_in;
107 wire [15:0] flags_out;
5a2a82dc
MG
108 reg flags_write;
109
7f1b6bd9 110 reg [15:0] latest_news;
5a2a82dc 111
23c26e04
MG
112 RAM #(.ADDRESS_BITS(3)) flags (.clk(clk), .write(flags_write), .addr(flags_addr[2:0]), .in(flags_in), .out(flags_out));
113
7f1b6bd9
MG
114 reg [15:0] flag_or_news;
115 reg [15:0] news_out;
23c26e04 116
3b542afc 117 news newspaper (.news_in(latest_news), .direction(flags_addr[1:0]), .news_out(news_out));
23c26e04 118
3b542afc 119 assign flag_or_news = flags_addr[3] ? news_out : flags_out;
5a2a82dc
MG
120
121 always @ (posedge clk) begin
122 if(mem_write)
123 mem_write <= 0;
23c26e04
MG
124 if(flags_write) begin
125 flags_write <= 0;
126 flags_addr_latch <= 0;
127 end
5a2a82dc
MG
128
129 case (op)
130 `OP_NOP: begin end
131
132 `OP_LOADA:
133 begin
134 alu_carry <= aluc;
23c26e04 135 F <= flag_or_news;
5a2a82dc
MG
136 A <= mem_out;
137 C <= mem_out;
138 io <= io_pin;
139 if (bsel)
140 B <= cube_in;
141 end
142
143 `OP_LOADB:
144 begin
145 alu_sum <= alus;
23c26e04 146 Cond <= inv ? ~flag_or_news : flag_or_news;
5a2a82dc
MG
147 B <= mem_out;
148 R <= mem_out;
149 end
150
151 `OP_STORE:
152 begin
7f1b6bd9 153 for(idx = 0; idx < 16; idx++) begin
23c26e04
MG
154 flags_in[idx] = Cond[idx] ? alu_carry_out[idx] : flags_out[idx];
155 latest_news[idx] <= flags_in[idx];
156 end
157 if(flags_addr) begin // we do not write to flag 0
158 flags_write <= 1;
159 flags_addr_latch <= flags_addr;
160 end
5a2a82dc
MG
161 mem_in <= alu_sum_out;
162 mem_write <= 1;
5a2a82dc
MG
163 end
164
7f1b6bd9 165 `OP_STOREI:
5a2a82dc 166 begin
7f1b6bd9
MG
167 mem_in <= I;
168 mem_write <= 1;
5a2a82dc 169 end
7f1b6bd9 170/*
5a2a82dc
MG
171 `OP_LOADI:
172 begin
173 C <= mem_out;
174 A <= I;
175 alu_sum <= 8'b11110000; // out of A, B, F, select exactly A
176 end
7f1b6bd9
MG
177*/
178
179 `OP_LED:
180 begin
181 if(!mode)
182 led_out <= leds;
183 else if(offset == 0)
184 led_out <= mem_out[3:0];
185 else if(offset == 1)
186 led_out <= mem_out[7:4];
187 else if(offset == 2)
188 led_out <= mem_out[11:8];
189 else if(offset == 3)
190 led_out <= mem_out[15:12];
191 end
5a2a82dc
MG
192
193/* `OP_RUG:
194 begin
195 if(!rw && ac && !news)
196 begin
197 rug[reg_] <= A;
198 C <= mem_out;
199 end
200 if(!rw && !ac && !news)
201 begin
202 rug[reg_] <= C;
203 A <= mem_out;
204 end
205 if(rw && ac && !news)
206 begin
207 A <= rug[reg_];
208 mem_in <= C;
209 end
210 if(rw && !ac && !news)
211 begin
212 C <= rug[reg_];
213 mem_in <= A;
214 end
215 if(rw && !ac && news)
216 begin
217 R <= mem_out;
218 cube_in <= mem_out;
219 end
220 if(rw && ac && news)
221 begin
222 cube_in <= mem_out;
223 end
224 end
225*/
226 endcase
227 end
228endmodule
This page took 0.025041 seconds and 4 git commands to generate.