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