├── Default.wcfg
├── LICENSE
├── bfcpu2.gise
├── bfcpu2.xise
├── irom.h
└── verilog
├── BrainfuckCore.v
├── Common.tf
├── Constants.v
├── Counter.v
├── DRAM.v
├── IROM.v
├── Stack.v
├── StageExecute.v
├── StageIDecode.v
├── StageIFetch.v
├── StageModify.v
├── StageTemplate.v
├── StageWriteback.v
└── UART.v
/Default.wcfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | clk
16 | clk
17 | true
18 | #ffff00
19 |
20 |
21 | reset
22 | reset
23 | true
24 | #808080
25 |
26 |
27 | pc_ce
28 | pc_ce
29 | true
30 | #00ffff
31 |
32 |
33 | pc[11:0]
34 | pc[11:0]
35 | true
36 | #ffa500
37 |
38 |
39 | ice
40 | ice
41 | true
42 | #00ffff
43 |
44 |
45 | ia[11:0]
46 | ia[11:0]
47 | true
48 | #ffff00
49 |
50 |
51 | id[7:0]
52 | id[7:0]
53 | true
54 | #ff00ff
55 |
56 |
57 | idecode_opcode[7:0]
58 | idecode_opcode[7:0]
59 | ASCIIRADIX
60 |
61 |
62 | execute_operation[7:0]
63 | execute_operation[7:0]
64 |
65 |
66 | writeback_operation[7:0]
67 | writeback_operation[7:0]
68 |
69 |
70 | do_mem_fetch
71 | do_mem_fetch
72 |
73 |
74 | do_reg_forward
75 | do_reg_forward
76 |
77 |
78 | execute_a[7:0]
79 | execute_a[7:0]
80 | true
81 | #ffa500
82 |
83 |
84 | dp[11:0]
85 | dp[11:0]
86 | true
87 | #ffa500
88 |
89 |
90 | drce
91 | drce
92 | true
93 | #00ffff
94 |
95 |
96 | dra[11:0]
97 | dra[11:0]
98 | true
99 | #ffff00
100 |
101 |
102 | drd[7:0]
103 | drd[7:0]
104 | true
105 | #ff00ff
106 |
107 |
108 | dwce
109 | dwce
110 | true
111 | #00ffff
112 |
113 |
114 | dwa[11:0]
115 | dwa[11:0]
116 | true
117 | #ffff00
118 |
119 |
120 | dwq[7:0]
121 | dwq[7:0]
122 | true
123 | #ff00ff
124 |
125 |
126 | cwre
127 | cwre
128 | true
129 | #00ffff
130 |
131 |
132 | cbsy
133 | cbsy
134 | true
135 | #00ffff
136 |
137 |
138 | label
139 | cq[7:0]
140 | cq[7:0]
141 | true
142 | #ff00ff
143 | cq[7:0]
144 |
145 |
146 | crda
147 | crda
148 | true
149 | #00ffff
150 |
151 |
152 | cack
153 | cack
154 | true
155 | #00ffff
156 |
157 |
158 | cd[7:0]
159 | cd[7:0]
160 | true
161 | #ff00ff
162 |
163 |
164 | idecode_ack
165 | idecode_ack
166 |
167 |
168 | execute_ack
169 | execute_ack
170 |
171 |
172 | writeback_ack
173 | writeback_ack
174 |
175 |
176 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011, 2012 Peter Zotov
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/bfcpu2.gise:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 11.1
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/bfcpu2.xise:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
--------------------------------------------------------------------------------
/irom.h:
--------------------------------------------------------------------------------
1 | @00000000
2 | 2b 2b 2b 2b 2b 5b 2d 5d
3 |
--------------------------------------------------------------------------------
/verilog/BrainfuckCore.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | `include "Common.tf"
3 | `include "Constants.v"
4 |
5 | module BrainfuckCore(
6 | clk,
7 | reset,
8 |
9 | /* IROM interface */
10 | ice,
11 | ia,
12 | id,
13 |
14 | /* DRAM read port */
15 | drce,
16 | dra,
17 | drd,
18 |
19 | /* DRAM write port */
20 | dwce,
21 | dwa,
22 | dwq,
23 |
24 | /* EXT read port */
25 | cd,
26 | crda,
27 | cack,
28 |
29 | /* EXT write port */
30 | cq,
31 | cwre,
32 | cbsy
33 | );
34 |
35 | parameter IA_WIDTH = 12;
36 | parameter ID_WIDTH = 8;
37 | parameter DA_WIDTH = 12;
38 | parameter DD_WIDTH = 8;
39 |
40 | input clk;
41 | input reset;
42 |
43 | wire [IA_WIDTH - 1:0] pc;
44 | wire pc_ce;
45 |
46 | Counter #(
47 | .WIDTH(IA_WIDTH)
48 | ) reg_pc (
49 | .clk(clk),
50 | .reset(reset),
51 | .ce(pc_ce),
52 | .q(pc),
53 | .d(12'b0),
54 | .load(1'b0),
55 | .down(1'b0)
56 | );
57 |
58 | wire [DA_WIDTH - 1:0] dp;
59 | wire dp_ce, dp_down;
60 |
61 | Counter #(
62 | .WIDTH(DA_WIDTH)
63 | ) reg_dp (
64 | .clk(clk),
65 | .reset(reset),
66 | .ce(dp_ce),
67 | .q(dp),
68 | .d(12'b0),
69 | .load(1'b0),
70 | .down(dp_down)
71 | );
72 |
73 | output ice;
74 | output [IA_WIDTH - 1:0] ia;
75 | input [ID_WIDTH - 1:0] id;
76 |
77 | output drce, dwce;
78 | output [DA_WIDTH - 1:0] dra;
79 | output [DA_WIDTH - 1:0] dwa;
80 | input [DD_WIDTH - 1:0] drd;
81 | output [DD_WIDTH - 1:0] dwq;
82 |
83 | input [7:0] cd;
84 | input crda;
85 | output cack;
86 |
87 | output [7:0] cq;
88 | output cwre;
89 | input cbsy;
90 |
91 | wire [ID_WIDTH - 1:0] idecode_opcode;
92 | wire idecode_ack;
93 |
94 | wire [`OPCODE_MSB:0] execute_operation;
95 | wire execute_ack;
96 | wire [DD_WIDTH - 1:0] execute_a;
97 |
98 | wire [`OPCODE_MSB:0] writeback_operation;
99 | wire writeback_ack;
100 | wire [DA_WIDTH - 1:0] writeback_dp;
101 |
102 | /*
103 | * Fetch instruction, taking memory delays into
104 | * account.
105 | * This stage prefetches one instruction.
106 | */
107 | StageIFetch #(
108 | .A_WIDTH(IA_WIDTH),
109 | .D_WIDTH(ID_WIDTH)
110 | ) ifetch (
111 | .clk(clk),
112 | .reset(reset),
113 |
114 | /* PC register value, to get instruction address */
115 | .pc(pc),
116 |
117 | /* Has ifetch got an instruction last cycle? */
118 | .step_pc(pc_ce),
119 |
120 | /* IROM interface */
121 | .ice(ice),
122 | .ia(ia),
123 | .id(id),
124 |
125 | .opcode(idecode_opcode),
126 | .ack_in(idecode_ack)
127 | );
128 |
129 | /*
130 | * Decode instruction. IDecode has fixed 8 bit width.
131 | */
132 | StageIDecode idecode (
133 | .clk(clk),
134 | .reset(reset),
135 |
136 | .opcode_in(idecode_opcode),
137 | .ack(idecode_ack),
138 |
139 | .operation(execute_operation),
140 | .ack_in(execute_ack)
141 | );
142 |
143 | /*
144 | * Execute the instruction.
145 | * This stage prefetches one datum and maintains cache consistency
146 | * on data pointer updates.
147 | */
148 | StageExecute #(
149 | .A_WIDTH(DA_WIDTH),
150 | .D_WIDTH(DD_WIDTH)
151 | ) execute (
152 | .clk(clk),
153 | .reset(reset),
154 |
155 | /* DP register value, to get a datum */
156 | .dp(dp),
157 |
158 | /* DP register increment and decrement control lines */
159 | .dp_ce(dp_ce),
160 | .dp_down(dp_down),
161 |
162 | /* DP register cache, to avoid WAW(mem,dp) hazard */
163 | .dp_cache(writeback_dp),
164 |
165 | /* DRAM read port interface */
166 | .dce(drce),
167 | .da(dra),
168 | .dd(drd),
169 |
170 | /* EXT read port interface */
171 | .cd(cd),
172 | .crda(crda),
173 | .cack(cack),
174 |
175 | /* Accumulator output */
176 | .a(execute_a),
177 |
178 | .operation_in(execute_operation),
179 | .ack(execute_ack),
180 |
181 | .operation(writeback_operation),
182 | .ack_in(writeback_ack)
183 | );
184 |
185 | /*
186 | * Write accumulator back to DRAM or to I/O module.
187 | */
188 | StageWriteback #(
189 | .A_WIDTH(DA_WIDTH),
190 | .D_WIDTH(DD_WIDTH)
191 | ) writeback (
192 | .clk(clk),
193 | .reset(reset),
194 |
195 | /* DP register value, to write a datum */
196 | .dp(writeback_dp),
197 |
198 | /* DRAM write port interface */
199 | .dce(dwce),
200 | .da(dwa),
201 | .dq(dwq),
202 |
203 | /* EXT write port interface */
204 | .cq(cq),
205 | .cwre(cwre),
206 | .cbsy(cbsy),
207 |
208 | /* Accumulator input */
209 | .a_in(execute_a),
210 |
211 | .operation_in(writeback_operation),
212 | .ack(writeback_ack),
213 |
214 | /* The last stage has ACK always asserted. */
215 | .ack_in(1'b1)
216 | );
217 | endmodule
218 |
219 | module BrainfuckCoreTest;
220 | reg clk;
221 | reg reset;
222 |
223 | wire ce, drce, dwce;
224 | wire [11:0] ia;
225 | wire [11:0] dra;
226 | wire [11:0] dwa;
227 | wire [7:0] id;
228 | wire [7:0] drd;
229 | wire [7:0] dwq;
230 | wire cack, cwre;
231 | reg crda, cbsy;
232 | reg [7:0] cd;
233 | wire [7:0] cq;
234 |
235 | BrainfuckCore uut (
236 | .clk(clk),
237 | .reset(reset),
238 |
239 | .ice(ice),
240 | .ia(ia),
241 | .id(id),
242 |
243 | .drce(drce),
244 | .dra(dra),
245 | .drd(drd),
246 |
247 | .dwce(dwce),
248 | .dwa(dwa),
249 | .dwq(dwq),
250 |
251 | .cd(cd),
252 | .crda(crda),
253 | .cack(cack),
254 |
255 | .cq(cq),
256 | .cwre(cwre),
257 | .cbsy(cbsy)
258 | );
259 |
260 | IROM irom (
261 | .clk(clk),
262 | .ce(ice),
263 | .a(ia),
264 | .q(id)
265 | );
266 |
267 | DRAM dram (
268 | .clk(clk),
269 | .rce(drce),
270 | .ra(dra),
271 | .rq(drd),
272 | .wce(dwce),
273 | .wa(dwa),
274 | .wd(dwq)
275 | );
276 |
277 | initial begin
278 | clk = 0;
279 | reset = 0;
280 | crda = 0;
281 |
282 | `reset
283 |
284 | #161; crda = 1; cd = 8'h42;
285 | #20; cd = 8'h43;
286 | #20; crda = 0; cd = 0;
287 | end
288 |
289 | always begin
290 | `step
291 | end
292 |
293 | reg [1:0] uart_wait = 2'b00;
294 | always @(posedge clk) begin
295 | if (cwre) begin
296 | $write("%c", cq);
297 | cbsy <= 1'b1;
298 | uart_wait <= 2'b11;
299 | end else begin
300 | if (uart_wait)
301 | uart_wait <= uart_wait - 1;
302 | else
303 | cbsy <= 1'b0;
304 | end
305 | end
306 |
307 | endmodule
308 |
--------------------------------------------------------------------------------
/verilog/Common.tf:
--------------------------------------------------------------------------------
1 | `define reset reset = 1; `step `step reset = 0; #20;
2 | `define step clk = 1; #10; clk = 0; #10;
--------------------------------------------------------------------------------
/verilog/Constants.v:
--------------------------------------------------------------------------------
1 | `define OPCODE_MSB 7
2 |
3 | `define OP_INCDP 0 // >
4 | `define OP_DECDP 1 // <
5 | `define OP_INC 2 // +
6 | `define OP_DEC 3 // -
7 | `define OP_OUT 4 // .
8 | `define OP_IN 5 // ,
9 | `define OP_LOOPBEGIN 6 // [
10 | `define OP_LOOPEND 7 // ]
11 |
--------------------------------------------------------------------------------
/verilog/Counter.v:
--------------------------------------------------------------------------------
1 | module Counter (
2 | clk,
3 | reset,
4 | ce,
5 | d,
6 | q,
7 | load,
8 | down
9 | );
10 |
11 | parameter WIDTH = 8;
12 |
13 | input clk;
14 | input reset;
15 | input ce;
16 | input [WIDTH - 1:0] d;
17 | output reg [WIDTH - 1:0] q;
18 | input load;
19 | input down;
20 |
21 | always @(posedge clk) begin
22 | if (reset)
23 | q <= 0;
24 | else if (ce) begin
25 | if (load)
26 | q <= d;
27 | else if(down)
28 | q <= q - 1;
29 | else /* !load && !down */
30 | q <= q + 1;
31 | end
32 | end
33 |
34 | endmodule
35 |
--------------------------------------------------------------------------------
/verilog/DRAM.v:
--------------------------------------------------------------------------------
1 | module DRAM (
2 | clk,
3 | rce,
4 | ra,
5 | rq,
6 | wce,
7 | wa,
8 | wd
9 | );
10 |
11 | parameter D_WIDTH = 8;
12 | parameter A_WIDTH = 12;
13 | parameter A_DEPTH = (1 << A_WIDTH);
14 |
15 | input clk;
16 |
17 | input rce;
18 | input [A_WIDTH - 1:0] ra;
19 | output reg [D_WIDTH - 1:0] rq;
20 |
21 | input wce;
22 | input [A_WIDTH - 1:0] wa;
23 | input [D_WIDTH - 1:0] wd;
24 |
25 | reg [D_WIDTH - 1:0] memory[0:A_DEPTH - 1];
26 |
27 | always @(posedge clk) begin
28 | if (rce)
29 | rq <= memory[ra];
30 |
31 | if (wce)
32 | memory[wa] <= wd;
33 | end
34 |
35 | integer i;
36 | initial
37 | begin
38 | for(i = 0; i < A_DEPTH; i = i + 1)
39 | memory[i] = 0;
40 | end
41 |
42 | endmodule
43 |
--------------------------------------------------------------------------------
/verilog/IROM.v:
--------------------------------------------------------------------------------
1 | module IROM (
2 | clk,
3 | ce,
4 | a,
5 | q
6 | );
7 |
8 | parameter D_WIDTH = 8;
9 | parameter A_WIDTH = 12;
10 | parameter A_DEPTH = (1 << A_WIDTH);
11 |
12 | input clk;
13 | input ce;
14 |
15 | input [A_WIDTH - 1:0] a;
16 | output reg [D_WIDTH - 1:0] q;
17 |
18 | reg [D_WIDTH - 1:0] memory[0:A_DEPTH - 1];
19 |
20 | always @(posedge clk) begin
21 | if(ce)
22 | q <= memory[a];
23 | end
24 |
25 | integer i;
26 | initial
27 | begin
28 | for(i = 0; i < A_DEPTH; i = i + 1)
29 | memory[i] = 0;
30 |
31 | $readmemh("irom.h", memory);
32 | end
33 |
34 | endmodule
35 |
--------------------------------------------------------------------------------
/verilog/Stack.v:
--------------------------------------------------------------------------------
1 | module Stack (
2 | clk,
3 | reset,
4 | q,
5 | d,
6 | push,
7 | pop,
8 | );
9 |
10 | parameter WIDTH = 11;
11 | parameter DEPTH = 7;
12 |
13 | input clk;
14 | input reset;
15 | input [WIDTH - 1:0] d;
16 | output reg [WIDTH - 1:0] q;
17 | input push;
18 | input pop;
19 |
20 | reg [DEPTH - 1:0] ptr;
21 | reg [WIDTH - 1:0] stack [0:(1 << DEPTH) - 1];
22 |
23 | always @(posedge clk) begin
24 | if (reset)
25 | ptr <= 0;
26 | else if (push)
27 | ptr <= ptr + 1;
28 | else if (pop)
29 | ptr <= ptr - 1;
30 | end
31 |
32 | always @(posedge clk) begin
33 | if (push || pop) begin
34 | if(push)
35 | stack[ptr] <= q;
36 |
37 | q <= stack[ptr - 1];
38 | end
39 | end
40 |
41 | endmodule
--------------------------------------------------------------------------------
/verilog/StageExecute.v:
--------------------------------------------------------------------------------
1 | `include "Constants.v"
2 |
3 | module StageExecute (
4 | clk,
5 | reset,
6 |
7 | dp,
8 | dp_ce,
9 | dp_down,
10 |
11 | dp_cache,
12 |
13 | dce,
14 | da,
15 | dd,
16 |
17 | cd,
18 | crda,
19 | cack,
20 |
21 | a,
22 |
23 | operation_in,
24 | ack_in,
25 |
26 | operation,
27 | ack
28 | );
29 |
30 | parameter A_WIDTH = 12;
31 | parameter D_WIDTH = 8;
32 |
33 | input clk;
34 | input reset;
35 |
36 | input [A_WIDTH - 1:0] dp;
37 | output dp_ce;
38 | output dp_down;
39 |
40 | output dce;
41 | output [A_WIDTH - 1:0] da;
42 | input [D_WIDTH - 1:0] dd;
43 |
44 | input [7:0] cd;
45 | input crda;
46 | output cack;
47 |
48 | output reg [D_WIDTH - 1:0] a;
49 |
50 | input [`OPCODE_MSB:0] operation_in;
51 | output ack;
52 |
53 | output reg [`OPCODE_MSB:0] operation;
54 | input ack_in;
55 |
56 | reg prefetched;
57 |
58 | /*
59 | * Data pointer manipulation
60 | */
61 | assign dp_ce = ack_in && (operation_in[`OP_INCDP] || operation_in[`OP_DECDP]);
62 | assign dp_down = ack_in && operation_in[`OP_DECDP];
63 |
64 | output reg [A_WIDTH - 1:0] dp_cache;
65 |
66 | /*
67 | * RAW hazard handling: register forwarding
68 | */
69 | wire dirty_datum;
70 | assign dirty_datum = operation[`OP_INC] || operation[`OP_DEC] ||
71 | operation[`OP_IN] ||
72 | /* These do not make change the datum. It is an optimization: *
73 | * memfetch costs 2 cycles, and regforward only one. */
74 | operation[`OP_LOOPBEGIN] || operation[`OP_LOOPEND];
75 |
76 | wire do_mem_fetch, do_reg_forward;
77 |
78 | assign do_mem_fetch = need_fetch_mem && !dirty_datum;
79 | assign do_reg_forward = need_fetch_mem && dirty_datum;
80 |
81 | /*
82 | * Reading from DRAM
83 | */
84 | wire need_fetch_mem;
85 | assign need_fetch_mem = (operation_in[`OP_INC] || operation_in[`OP_DEC] ||
86 | operation_in[`OP_OUT] || operation_in[`OP_LOOPBEGIN] ||
87 | operation_in[`OP_LOOPEND]);
88 |
89 | assign da = dp;
90 | assign dce = do_mem_fetch;
91 |
92 | wire [D_WIDTH - 1:0] data_input;
93 | assign data_input = do_reg_forward ? a : dd;
94 |
95 | assign datum_ready = (do_mem_fetch && prefetched) || do_reg_forward;
96 |
97 | /*
98 | * Reading from EXT
99 | */
100 | wire need_fetch_ext;
101 | assign need_fetch_ext = operation_in[`OP_IN];
102 |
103 | assign cack = crda && need_fetch_ext;
104 |
105 | /*
106 | * Wait states
107 | */
108 | wire ext_wait;
109 | assign ext_wait = (need_fetch_ext && !crda) || (do_mem_fetch && !prefetched);
110 |
111 | /*
112 | * ACKing the previous stage
113 | */
114 | assign ack = ack_in && !ext_wait;
115 |
116 | always @(posedge clk) begin
117 | if (reset)
118 | prefetched <= 0;
119 | else
120 | prefetched <= do_mem_fetch;
121 | end
122 |
123 | always @(posedge clk) begin
124 | if (reset) begin
125 | operation <= 0;
126 |
127 | dp_cache <= 0;
128 | a <= 0;
129 | end else begin
130 | dp_cache <= dp;
131 |
132 | if (ack_in && ext_wait) begin
133 | operation <= 0; /* Bubble */
134 | a <= 0;
135 | end else if(ack_in) begin
136 | operation <= operation_in;
137 |
138 | if (datum_ready)
139 | if (operation_in[`OP_INC])
140 | a <= data_input + 1;
141 | else if (operation_in[`OP_DEC])
142 | a <= data_input - 1;
143 | else
144 | a <= data_input;
145 | else if (need_fetch_ext && crda)
146 | a <= cd;
147 | else
148 | a <= 0;
149 | end
150 | end
151 | end
152 |
153 | endmodule
154 |
--------------------------------------------------------------------------------
/verilog/StageIDecode.v:
--------------------------------------------------------------------------------
1 | `include "Constants.v"
2 |
3 | module StageIDecode (
4 | clk,
5 | reset,
6 |
7 | opcode_in,
8 | ack,
9 |
10 | operation,
11 | ack_in
12 | );
13 |
14 | input clk;
15 | input reset;
16 |
17 | input [7:0] opcode_in;
18 | output ack;
19 |
20 | output reg [`OPCODE_MSB:0] operation;
21 | input ack_in;
22 |
23 | assign ack = ack_in;
24 |
25 | always @(posedge clk) begin
26 | if (reset) begin
27 | operation <= 0;
28 | end else begin
29 | if (ack_in) begin
30 | case (opcode_in)
31 | 8'h3E: operation <= 8'b0000_0001;
32 | 8'h3C: operation <= 8'b0000_0010;
33 | 8'h2B: operation <= 8'b0000_0100;
34 | 8'h2D: operation <= 8'b0000_1000;
35 | 8'h2E: operation <= 8'b0001_0000;
36 | 8'h2C: operation <= 8'b0010_0000;
37 | 8'h5B: operation <= 8'b0100_0000;
38 | 8'h5D: operation <= 8'b1000_0000;
39 |
40 | default: operation <= 8'b0000_0000;
41 | endcase
42 | end
43 | end
44 | end
45 |
46 | endmodule
47 |
--------------------------------------------------------------------------------
/verilog/StageIFetch.v:
--------------------------------------------------------------------------------
1 | module StageIFetch (
2 | clk,
3 | reset,
4 |
5 | pc,
6 |
7 | ice,
8 | ia,
9 | id,
10 |
11 | step_pc,
12 |
13 | opcode,
14 | ack_in
15 | );
16 |
17 | parameter A_WIDTH = 12;
18 | parameter D_WIDTH = 8;
19 |
20 | input clk;
21 | input reset;
22 |
23 | input [A_WIDTH - 1:0] pc;
24 |
25 | output ice;
26 | output [A_WIDTH - 1:0] ia;
27 | input [D_WIDTH - 1:0] id;
28 |
29 | output step_pc;
30 |
31 | output reg [D_WIDTH - 1:0] opcode;
32 |
33 | input ack_in;
34 |
35 | assign ia = pc;
36 | assign ice = !reset && ack_in;
37 |
38 | /*
39 | * step_pc=1 means that at the _next_ cycle PC will be
40 | * increased. Thus, if we will do a successful fetch
41 | * _now_, we should increase it _then_.
42 | */
43 | assign step_pc = !reset && ack_in;
44 |
45 | reg prefetched;
46 |
47 | always @(posedge clk) begin
48 | if (reset) begin
49 | prefetched <= 0;
50 |
51 | opcode <= 0;
52 | end else begin
53 | prefetched <= 1'b1;
54 |
55 | if (ack_in && prefetched)
56 | opcode <= id;
57 | end
58 | end
59 |
60 | endmodule
61 |
--------------------------------------------------------------------------------
/verilog/StageModify.v:
--------------------------------------------------------------------------------
1 | `include "Constants.v"
2 |
3 | module StageModify (
4 | clk,
5 | reset,
6 |
7 | a_in,
8 | a,
9 |
10 | operation_in,
11 | ack_in,
12 |
13 | operation,
14 | ack
15 | );
16 |
17 | parameter D_WIDTH = 8;
18 |
19 | input clk;
20 | input reset;
21 |
22 | input [D_WIDTH - 1:0] a_in;
23 | output reg [D_WIDTH - 1:0] a;
24 |
25 | input [`OPCODE_MSB:0] operation_in;
26 | output ack;
27 |
28 | output reg [`OPCODE_MSB:0] operation;
29 | input ack_in;
30 |
31 | assign ack = ack_in;
32 |
33 | always @(posedge clk) begin
34 | if (reset) begin
35 | operation <= 0;
36 |
37 | a <= 0;
38 | end else begin
39 | if (ack_in) begin
40 | operation <= operation_in;
41 |
42 | if (operation_in[`OP_INC])
43 | a <= a_in + 1;
44 | else if (operation_in[`OP_DEC])
45 | a <= a_in - 1;
46 | else if (operation_in[`OP_IN] || operation_in[`OP_OUT])
47 | a <= a_in;
48 | else
49 | a <= 0;
50 | end
51 | end
52 | end
53 |
54 | endmodule
55 |
--------------------------------------------------------------------------------
/verilog/StageTemplate.v:
--------------------------------------------------------------------------------
1 | `include "Constants.v"
2 |
3 | module StageX (
4 | clk,
5 | reset,
6 |
7 | operation_in,
8 | ack_in,
9 |
10 | operation,
11 | ack,
12 | );
13 |
14 | input clk;
15 | input reset;
16 |
17 | input [`OPCODE_MSB:0] operation_in;
18 | output reg ack;
19 |
20 | output reg [`OPCODE_MSB:0] operation;
21 | input ack_in;
22 |
23 | assign ack = ack_in;
24 |
25 | always @(posedge clk) begin
26 | if (reset) begin
27 | operation <= 0;
28 | end else begin
29 | if (ack_in) begin
30 | operation <= operation_in;
31 | end
32 | end
33 | end
34 |
35 | endmodule
36 |
--------------------------------------------------------------------------------
/verilog/StageWriteback.v:
--------------------------------------------------------------------------------
1 | `include "Constants.v"
2 |
3 | module StageWriteback (
4 | clk,
5 | reset,
6 |
7 | dp,
8 |
9 | dce,
10 | da,
11 | dq,
12 |
13 | cq,
14 | cwre,
15 | cbsy,
16 |
17 | a_in,
18 |
19 | operation_in,
20 | ack_in,
21 |
22 | operation,
23 | ack
24 | );
25 |
26 | parameter A_WIDTH = 12;
27 | parameter D_WIDTH = 8;
28 |
29 | input clk;
30 | input reset;
31 |
32 | input [A_WIDTH - 1:0] dp;
33 |
34 | output dce;
35 | output [A_WIDTH - 1:0] da;
36 | output [D_WIDTH - 1:0] dq;
37 |
38 | output [7:0] cq;
39 | output cwre;
40 | input cbsy;
41 |
42 | input [D_WIDTH - 1:0] a_in;
43 |
44 | input [`OPCODE_MSB:0] operation_in;
45 | output ack;
46 |
47 | output reg [`OPCODE_MSB:0] operation;
48 | input ack_in;
49 |
50 | /*
51 | * Writing to DRAM
52 | */
53 | wire need_write_mem;
54 | assign need_write_mem = (operation_in[`OP_INC] || operation_in[`OP_DEC] ||
55 | operation_in[`OP_IN]);
56 |
57 | assign da = dp;
58 | assign dce = need_write_mem;
59 | assign dq = a_in;
60 |
61 | /*
62 | * Writing to EXT
63 | */
64 | wire need_write_ext;
65 | assign need_write_ext = operation_in[`OP_OUT];
66 |
67 | assign cq = a_in;
68 | assign cwre = !cbsy && need_write_ext;
69 |
70 | wire ext_wait;
71 | assign ext_wait = need_write_ext && cbsy;
72 |
73 | /*
74 | * ACKing the previous stage
75 | */
76 | assign ack = ack_in && !ext_wait;
77 |
78 | always @(posedge clk) begin
79 | if (reset) begin
80 | operation <= 0;
81 | end else begin
82 | if (ack_in && !ext_wait)
83 | operation <= operation_in;
84 | else if (ack_in)
85 | operation <= 0; /* Bubble */
86 | end
87 | end
88 |
89 | endmodule
90 |
--------------------------------------------------------------------------------
/verilog/UART.v:
--------------------------------------------------------------------------------
1 | module UART(
2 | clk,
3 | reset,
4 | tx,
5 | rx,
6 | d,
7 | q,
8 | rda,
9 | ack,
10 | bsy,
11 | wre
12 | );
13 |
14 | input clk;
15 | input reset;
16 |
17 | output tx;
18 | input rx;
19 |
20 | input [7:0] d;
21 | output reg rda;
22 | input ack;
23 |
24 | output [7:0] q;
25 | output bsy;
26 | input wre;
27 |
28 | parameter SYS_CLOCK = 50000000;
29 | parameter BAUD = 9600;
30 |
31 | wire received;
32 |
33 | osdvu #(
34 | .CLOCK_DIVIDE(SYS_CLOCK / (BAUD * 4))
35 | ) uart (
36 | .clk(clk),
37 | .rst(reste),
38 | .rx(rx),
39 | .tx(tx),
40 | .transmit(wre),
41 | .tx_byte(d),
42 | .received(received),
43 | .rx_byte(q),
44 | .is_receiving(),
45 | .is_transmitting(bsy),
46 | .recv_error()
47 | );
48 |
49 | always @(posedge clk) begin
50 | if(reset || ack)
51 | rda <= 1'b0;
52 | else if(received)
53 | rda <= 1'b1;
54 | end
55 |
56 | endmodule
57 |
--------------------------------------------------------------------------------