Add diagrams and pictures
[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
46a95fd3 21module 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);
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
7f1b6bd9
MG
40 // OP_LED
41 wire mode = I[4];
42 wire [1:0] offset = I[1:0];
43 wire [3:0] leds = I[3:0];
5a2a82dc 44
7f1b6bd9
MG
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;
23c26e04
MG
52 reg [7:0] alu_sum = 0;
53 reg [7:0] alu_carry = 0;
7f1b6bd9 54 reg [15:0] cube_in;
5a2a82dc
MG
55
56 // these are not really regs
57
7f1b6bd9
MG
58 reg [15:0] alu_sum_out;
59 reg [15:0] alu_carry_out;
23c26e04 60
46a95fd3 61 reg [2:0] alu_index [15:0];
23c26e04
MG
62
63 reg [15:0] idx;
5a2a82dc
MG
64
65 always @* begin
7f1b6bd9 66 for(idx = 0; idx < 16; idx=idx+1) begin
23c26e04
MG
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
5a2a82dc
MG
71 end
72
23c26e04
MG
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
7f1b6bd9
MG
92 reg [15:0] flags_in;
93 wire [15:0] flags_out;
5a2a82dc
MG
94 reg flags_write;
95
7f1b6bd9 96 reg [15:0] latest_news;
5a2a82dc 97
23c26e04
MG
98 RAM #(.ADDRESS_BITS(3)) flags (.clk(clk), .write(flags_write), .addr(flags_addr[2:0]), .in(flags_in), .out(flags_out));
99
7f1b6bd9
MG
100 reg [15:0] flag_or_news;
101 reg [15:0] news_out;
23c26e04 102
46a95fd3 103 news newspaper (.news_in(latest_news), .direction(flags_addr[2:0]), .news_out(news_out));
23c26e04 104
3b542afc 105 assign flag_or_news = flags_addr[3] ? news_out : flags_out;
5a2a82dc
MG
106
107 always @ (posedge clk) begin
108 if(mem_write)
109 mem_write <= 0;
23c26e04
MG
110 if(flags_write) begin
111 flags_write <= 0;
112 flags_addr_latch <= 0;
113 end
5a2a82dc
MG
114
115 case (op)
116 `OP_NOP: begin end
117
118 `OP_LOADA:
119 begin
120 alu_carry <= aluc;
23c26e04 121 F <= flag_or_news;
5a2a82dc
MG
122 A <= mem_out;
123 C <= mem_out;
5a2a82dc
MG
124 if (bsel)
125 B <= cube_in;
126 end
127
128 `OP_LOADB:
129 begin
130 alu_sum <= alus;
23c26e04 131 Cond <= inv ? ~flag_or_news : flag_or_news;
5a2a82dc
MG
132 B <= mem_out;
133 R <= mem_out;
134 end
135
136 `OP_STORE:
137 begin
7f1b6bd9 138 for(idx = 0; idx < 16; idx++) begin
23c26e04
MG
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
5a2a82dc
MG
146 mem_in <= alu_sum_out;
147 mem_write <= 1;
5a2a82dc
MG
148 end
149
7f1b6bd9 150 `OP_STOREI:
5a2a82dc 151 begin
7f1b6bd9
MG
152 mem_in <= I;
153 mem_write <= 1;
5a2a82dc 154 end
7f1b6bd9 155/*
5a2a82dc
MG
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
7f1b6bd9
MG
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
5a2a82dc
MG
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
213endmodule
This page took 0.02395 seconds and 4 git commands to generate.