├── 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 | --------------------------------------------------------------------------------