浏览代码

Initial progress with faster design.

bartpleiter 2 月之前
父节点
当前提交
9b3e3a5eb7

+ 9 - 0
Assembler/simulateCPU.sh

@@ -0,0 +1,9 @@
+# Build script for assembly files for simulation in verilog (run from first address for CPU testing)
+if (python3 Assembler.py bdos 0x000000 > ../Verilog/memory/sram.list) # compile and write to verilog memory folder
+    then
+        iverilog -o /home/bart/Documents/FPGA/FPGC6/Verilog/output/output /home/bart/Documents/FPGA/FPGC6/Verilog/testbench/B32P_tb.v
+        vvp /home/bart/Documents/FPGA/FPGC6/Verilog/output/output
+    else
+        # print the error, which is in code.list
+        (cat ../Verilog/memory/sram.list)
+fi

+ 4 - 0
Assembler/testbus.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+iverilog -o /home/bart/Documents/FPGA/FPGC6/Verilog/output/output /home/bart/Documents/FPGA/FPGC6/Verilog/testbench/busProtocol_tb.v
+vvp /home/bart/Documents/FPGA/FPGC6/Verilog/output/output

+ 42 - 0
Verilog/memory/sram.list

@@ -0,0 +1,42 @@
+10010000000000000000000000001000 //Jump to constant address 4
+10010000000000000000000001010010 //Jump to constant address 41
+10010000000000000000000000001000 //Jump to constant address 4
+10010000000000000000000000001000 //Jump to constant address 4
+00011100000000000000010100010001 //Set r1 to 5
+00011100000000000000001000100010 //Set r2 to 2
+00000011000000000000000100100011 //Compute r1 + r2 and write result to r3
+00000011000000000000001100100011 //Compute r3 + r2 and write result to r3
+00000011000000000000000100110011 //Compute r1 + r3 and write result to r3
+00000011000000000000001100110011 //Compute r3 + r3 and write result to r3
+00011100000000000000100100010001 //Set r1 to 9
+00011100000000000000101000100010 //Set r2 to 10
+00000011000000000000000100100011 //Compute r1 + r2 and write result to r3
+00000011000000000000001100100011 //Compute r3 + r2 and write result to r3
+00000011000000000000000100110011 //Compute r1 + r3 and write result to r3
+00000011000000000000001100110011 //Compute r3 + r3 and write result to r3
+10110000000000000000000000010000 //Push r1 to stack
+10100000000000000000000000000010 //Pop from stack to r2
+00010011000000000000011000100100 //Compute r2 + 6 and write result to r4
+11010000000000000000000101000000 //Write value in r4 to address in r1 with offset 0
+11010000000000000001000100110000 //Write value in r3 to address in r1 with offset 1
+11100000000000000000000100000101 //Read at address in r1 with offset 0 to r5
+00010011000000000000000101010101 //Compute r5 + 1 and write result to r5
+10010000000000000000000000001000 //Jump to constant address 4
+11010000000000001010001100110000 //Write value in r3 to address in r3 with offset 10
+11010000000000000000001100010000 //Write value in r1 to address in r3 with offset 0
+11100000000000001010001100000100 //Read at address in r3 with offset 10 to r4
+00000011000000000000010000010101 //Compute r4 + r1 and write result to r5
+01100000000000000011010100010010 //(unsigned) If r5 > r1, then jump to offset 3
+11111111111111111111111111111111 //Halt
+00011100000000000000000000010001 //Set r1 to 0
+00011100000000000000000000100010 //Set r2 to 0
+00011100000000000000000110011001 //Set r9 to 1
+00011100000000000001001010101010 //Set r10 to 18
+10110000000000000000000010100000 //Push r10 to stack
+10100000000000000000000000001011 //Pop from stack to r11
+00000011000000000000101010101111 //Compute r10 + r10 and write result to r15
+01010000000000000000000000001100 //Save PC to r12
+00010011000000000000000111001101 //Compute r12 + 1 and write result to r13
+11111111111111111111111111111111 //Halt
+00011100000000000010010100010001 //Set r1 to 37
+01000000000000000000000000000000 //Return from interrupt

+ 0 - 108
Verilog/modules/CPU/Arbiter.v

@@ -1,108 +0,0 @@
-/*
-* Arbiter
-* Regulates access to the CPU memory bus from both Instruction and Data memory
-* Port a (instruction memory) will directly access the bus (no latency)
-* When port b (data memory) requests an access, it will stop port a when it is finished and give access to port b
-* This will give port b quite some latency, but as port b requests are more rare, this should be okay (and can be reduced by l1d cache)
-*/
-
-module Arbiter(
-    input clk,
-    input reset,
-
-    // port a (Instr)
-    input [31:0] addr_a,
-    input [31:0] data_a,
-    input        we_a,
-    input        start_a,
-    output       done_a,
-
-    // port b (Data)
-    input [31:0] addr_b,
-    input [31:0] data_b,
-    input        we_b,
-    input        start_b,
-    output       done_b,
-
-    // output (both ports)
-    output [31:0] q,
-
-    // bus
-    output [26:0] bus_addr,
-    output [31:0] bus_data,
-    output        bus_we ,
-    output        bus_start,
-    input [31:0]  bus_q,
-    input         bus_done
-);
-
-assign q = bus_q;
-
-assign bus_addr     = (!port_b_access) ? addr_a   : bus_addr_reg;
-assign bus_data     = (!port_b_access) ? data_a   : bus_data_reg;
-assign bus_we       = (!port_b_access) ? we_a     : bus_we_reg;
-assign bus_start    = (!port_b_access) ? start_a  : (bus_start_reg && !bus_done);
-
-assign done_a       = (!port_b_access) && bus_done;
-assign done_b       = (state == state_wait_b_done) && bus_done;
-
-
-reg port_b_access = 1'b0;
-
-reg [26:0] bus_addr_reg = 27'd0;
-reg [31:0] bus_data_reg = 32'd0;
-reg bus_we_reg          = 1'b0;
-reg bus_start_reg       = 1'b0;
-
-// state machine
-reg [2:0] state = 3'd0; // 0-7 states limit
-parameter state_idle            = 3'd0;
-parameter state_wait_b_done     = 3'd1;
-
-always @(posedge clk) 
-begin
-    if (reset)
-    begin
-        port_b_access   <= 1'b0;
-        
-        bus_addr_reg    <= 27'd0;
-        bus_data_reg    <= 32'd0;
-        bus_we_reg      <= 1'b0;
-        bus_start_reg   <= 1'b0;
-
-        state           <= state_idle;
-    end
-    else
-    begin
-        case(state)
-            state_idle: 
-            begin
-                // if port b is requested and port a is just finished
-                if (!start_a && bus_done && start_b)
-                begin
-                    // give access to port b before a starts a new request
-                    port_b_access   <= 1'b1;
-
-                    bus_addr_reg    <= addr_b;
-                    bus_data_reg    <= data_b;
-                    bus_we_reg      <= we_b;
-                    bus_start_reg   <= 1'b1;
-
-                    state <= state_wait_b_done;
-                end
-                
-            end
-            state_wait_b_done:
-            begin
-                if (bus_done)
-                begin
-                    // return access to port a
-                    state           <= state_idle;
-                    port_b_access   <= 1'b0;
-                end
-            end
-        endcase
-    end
-end
-
-endmodule

+ 57 - 176
Verilog/modules/CPU/CPU.v

@@ -24,101 +24,37 @@
 */
 
 module CPU(
-    input clk, reset,
-    output [26:0] bus_addr,
-    output [31:0] bus_data,
-    output        bus_we,
-    output        bus_start,
-    input [31:0]  bus_q,
-    input         bus_done,
-
-    // sdram bus
-    output [23:0] sdc_addr,     // bus_addr
-    output [31:0] sdc_data,     // bus_data
-    output        sdc_we,       // bus_we
-    output        sdc_start,    // bus_start
-    input [31:0]  sdc_q,        // bus_q
-    input         sdc_done,     // bus_done
-
-    input int1, int2, int3, int4, int5, int6, int7, int8, int9, int10,
-
-    output [26:0] PC
+    input clk, clk100, reset,
+
+    // SDRAM bus for instruction and data memory
+    output [26:0] bus_i_sdram_addr,
+    output [31:0] bus_i_sdram_data,
+    output        bus_i_sdram_we,
+    output        bus_i_sdram_start,
+    input [31:0]  bus_i_sdram_q,
+    input         bus_i_sdram_done,
+    input         bus_i_sdram_ready,
+
+    output [26:0] bus_d_sdram_addr,
+    output [31:0] bus_d_sdram_data,
+    output        bus_d_sdram_we,
+    output        bus_d_sdram_start,
+    input [31:0]  bus_d_sdram_q,
+    input         bus_d_sdram_done,
+    input         bus_d_sdram_ready,
+
+    // ROM bus for instruction memory
+    output [8:0] bus_i_rom_addr,
+    input [31:0] bus_i_rom_q,
+
+    input int1, int2, int3, int4, int5, int6, int7, int8, int9, int10
 );
 
-parameter PCstart = 27'hC02522; // internal ROM addr 0 //27'hC02522;
+parameter PCstart = 27'h000000; // internal SRAM addr 0 //27'h000000;
+parameter PCinterruptValidFrom = 27'd100; // interrupt valid after address 100
 parameter PCincrease = 1'b1; // number of addresses to increase the PC with after each instruction
 parameter InterruptJumpAddr = 27'd1;
 
-/*
-* CPU BUS
-*/
-
-wire [31:0] arbiter_q;
-
-wire [31:0] addr_a;
-wire [31:0] data_a;
-wire        we_a;
-wire        start_a;
-wire        done_a;
-
-wire [31:0] addr_b;
-wire [31:0] data_b;
-wire        we_b;
-wire        start_b;
-wire        done_b;
-
-wire [26:0] arbiter_bus_addr;     // bus_addr
-wire [31:0] arbiter_bus_data;     // bus_data
-wire        arbiter_bus_we;       // bus_we
-wire        arbiter_bus_start;    // bus_start
-wire [31:0] arbiter_bus_q;        // bus_q
-wire        arbiter_bus_done;     // bus_done
-
-// bus splitter
-assign sdc_addr =   (arbiter_bus_addr < 27'h800000) ? arbiter_bus_addr: 24'd0;
-assign sdc_data =   (arbiter_bus_addr < 27'h800000) ? arbiter_bus_data: 32'd0;
-assign sdc_we =     (arbiter_bus_addr < 27'h800000) ? arbiter_bus_we: 1'b0;
-assign sdc_start =  (arbiter_bus_addr < 27'h800000) ? arbiter_bus_start: 1'b0;
-
-assign bus_addr =   (arbiter_bus_addr < 27'h800000) ? 27'd0: arbiter_bus_addr;
-assign bus_data =   (arbiter_bus_addr < 27'h800000) ? 32'd0: arbiter_bus_data;
-assign bus_we =     (arbiter_bus_addr < 27'h800000) ? 1'b0: arbiter_bus_we;
-assign bus_start =  (arbiter_bus_addr < 27'h800000) ? 1'b0: arbiter_bus_start;
-
-assign arbiter_bus_q =      (arbiter_bus_addr < 27'h800000) ? sdc_q: bus_q;
-assign arbiter_bus_done =   (arbiter_bus_addr < 27'h800000) ? sdc_done: bus_done;
-
-Arbiter arbiter (
-.clk(clk),
-.reset(reset),
-
-// port a (Instr)
-.addr_a(addr_a),
-.data_a(data_a),
-.we_a(we_a),
-.start_a(start_a),
-.done_a(done_a),
-
-// port b (Data)
-.addr_b(addr_b),
-.data_b(data_b),
-.we_b(we_b),
-.start_b(start_b),
-.done_b(done_b),
-
-// output (both ports)
-.q(arbiter_q),
-
-// bus
-.bus_addr(arbiter_bus_addr),
-.bus_data(arbiter_bus_data),
-.bus_we(arbiter_bus_we),
-.bus_start(arbiter_bus_start),
-.bus_q(arbiter_bus_q),
-.bus_done(arbiter_bus_done)
-);
-
-
 /*
 * Interrupts
 */
@@ -147,7 +83,6 @@ IntController intController(
 );
 
 
-
 // Registers for flush, stall and forwarding
 reg flush_FE, flush_DE, flush_EX, flush_MEM, flush_WB;
 reg stall_FE, stall_DE, stall_EX, stall_MEM, stall_WB;
@@ -161,25 +96,24 @@ wire datamem_busy_MEM;
 * FETCH (FE)
 */
 
-// Program Counter, start at ROM[0]
+// Program Counter, initialize to address with initial code
 reg [31:0]  pc_FE = PCstart;
+reg [31:0]  pc_FE_prev;
 
 reg [31:0]  pc_FE_backup = 32'd0;
 
 wire [31:0] pc4_FE;
-assign pc4_FE = pc_FE + 1'b1;
+assign pc4_FE = pc_FE + PCincrease;
 
-assign PC = pc_FE;
 
 wire [31:0] PC_backup_current;
 assign PC_backup_current = pc4_EX - PCincrease;
 
 // branch/jump/halt properly aligns interrupt with pipeline, as if it was a normal jump
-//  this fixed all instability since the addition of caching (because this decreased the time to obtain instructions)
 assign interruptValid = (
     intCPU && 
     !intDisabled && 
-    PC_backup_current < PCstart && 
+    PC_backup_current >= PCinterruptValidFrom && 
     (
         branch_MEM || jumpr_MEM || jumpc_MEM || halt_MEM
     )
@@ -190,11 +124,13 @@ begin
     if (reset)
     begin
         pc_FE <= PCstart;
+        pc_FE_prev <= 32'd0;
         pc_FE_backup <= 32'd0;
         intDisabled <= 1'b0;
     end
     else
     begin
+        pc_FE_prev <= pc_FE;
         // interrupt has highest priority
         if (interruptValid)
         begin
@@ -224,57 +160,31 @@ begin
 end
 
 
-//------------L1i Cache--------------
-//CPU bus
-wire [31:0]      l1i_addr;  // address to write or to start reading from
-wire [31:0]      l1i_data;  // data to write
-wire             l1i_we;    // write enable
-wire             l1i_start; // start trigger
-wire [31:0]      l1i_q;     // memory output
-wire             l1i_done;  // output ready
-
-L1Icache l1icache(
-.clk            (clk),
-.reset          (reset),
-.cache_reset    (clearCache_EX | clearCache_MEM),
-
-// CPU bus
-.l2_addr       (l1i_addr),
-.l2_data       (l1i_data),
-.l2_we         (l1i_we),
-.l2_start      (l1i_start),
-.l2_q          (l1i_q),
-.l2_done       (l1i_done),
-
-// sdram bus
-.sdc_addr       (addr_a),
-.sdc_data       (data_a),
-.sdc_we         (we_a),
-.sdc_start      (start_a),
-.sdc_q          (arbiter_q),
-.sdc_done       (done_a)
-);
-
-
 // Instruction Memory
 //  should eventually become a memory with variable latency
 // writes directly to next stage
 wire [31:0] instr_DE;
+wire [31:0] pc_FE_wire;
+assign pc_FE_wire = (stall_FE) ? pc_FE_prev : pc_FE;
 
 InstrMem instrMem(
-.clk(clk), 
+.clk(clk),
+.clk100(clk100),
 .reset(reset),
-.addr(pc_FE),
+.addr(pc_FE_wire),
 .q(instr_DE),
 .hit(instr_hit_FE),
 
-// bus
-.bus_addr(l1i_addr),
-.bus_data(l1i_data),
-.bus_we(l1i_we),
-.bus_start(l1i_start),
-.bus_q(l1i_q),
-.bus_done(l1i_done),
+// bus_rom
+.bus_i_rom_addr(bus_i_rom_addr),
+.bus_i_rom_q(bus_i_rom_q),
+
+// bus_l1i
+.bus_l1i_addr(addr_a),
+.bus_l1i_start(start_a),
+.bus_l1i_q(arbiter_q),
+.bus_l1i_done(done_a),
+.bus_l1i_ready(ready_a),
 
 .hold(stall_FE),
 .clear(flush_FE)
@@ -659,36 +569,7 @@ begin
     endcase
 end
 
-//------------L1d Cache--------------
-//CPU bus
-wire [31:0]      l1d_addr;  // address to write or to start reading from
-wire [31:0]      l1d_data;  // data to write
-wire             l1d_we;    // write enable
-wire             l1d_start; // start trigger
-wire [31:0]      l1d_q;     // memory output
-wire             l1d_done;  // output ready
-
-L1Dcache l1dcache(
-.clk            (clk),
-.reset          (reset),
-.cache_reset    (clearCache_EX | clearCache_MEM),
-
-// CPU bus
-.l2_addr       (l1d_addr),
-.l2_data       (l1d_data),
-.l2_we         (l1d_we),
-.l2_start      (l1d_start),
-.l2_q          (l1d_q),
-.l2_done       (l1d_done),
-
-// sdram bus
-.sdc_addr       (addr_b),
-.sdc_data       (data_b),
-.sdc_we         (we_b),
-.sdc_start      (start_b),
-.sdc_q          (arbiter_q),
-.sdc_done       (done_b)
-);
+
 
 
 // Data Memory
@@ -709,12 +590,13 @@ DataMem dataMem(
 .busy(datamem_busy_MEM),
 
 // bus
-.bus_addr(l1d_addr),
-.bus_data(l1d_data),
-.bus_we(l1d_we),
-.bus_start(l1d_start),
-.bus_q(l1d_q),
-.bus_done(l1d_done),
+.bus_addr(addr_b),
+.bus_data(data_b),
+.bus_we(we_b),
+.bus_start(start_b),
+.bus_q(arbiter_q),
+.bus_done(done_b),
+.bus_ready(ready_b),
 
 .hold(stall_MEM),
 .clear(flush_MEM)
@@ -778,7 +660,6 @@ Regr #(.N(3)) regr_cuflags_MEM_WB(
 /*
 * WRITE BACK (WB)
 */
-wire [15:0] const16u_WB;
 
 InstructionDecoder instrDec_WB(
 .instr(instr_WB),
@@ -788,7 +669,7 @@ InstructionDecoder instrDec_WB(
 
 .constAlu(),
 .const16(),
-.const16u(const16u_WB),
+.const16u(),
 .const27(),
 
 .areg(),
@@ -906,4 +787,4 @@ begin
 end
 
 
-endmodule
+endmodule

+ 14 - 16
Verilog/modules/CPU/DataMem.v

@@ -18,41 +18,39 @@ module DataMem(
     output        bus_start,
     input [31:0]  bus_q,
     input         bus_done,
+    input         bus_ready,
 
     input wire          clear, hold
 );
 
 reg [31:0] qreg = 32'd0;
+reg busy_reg = 1'b0;
+
+wire read_or_write = we || re;
+reg read_or_write_prev = 1'b0;
+wire read_or_write_edge = read_or_write && !read_or_write_prev;
 
 assign bus_addr = addr;
 assign bus_data = data;
 assign bus_we = we;
-assign bus_start = !bus_done && (we || re);
-assign busy = bus_start;
+assign bus_start = read_or_write_edge;
+assign busy = read_or_write && !bus_done;
 assign q = (bus_done) ? bus_q : qreg;
 
+
+
+// Clear and Hold are currently skipped because they are not used in the CPU
+
 always @(posedge clk)
 begin
-    // skip clear, because currently not needed
-    /*if (clear)
-    begin
-        q <= 32'd0;
-    end
-    else */
-    // skip hold, because currently not needed
-    /*
-    if (hold)
-    begin
-        q <= q;
-    end
-    else */
-
     if (reset)
     begin
+        read_or_write_prev <= 1'b0;
         qreg <= 32'd0;
     end
     else
     begin
+        read_or_write_prev <= read_or_write;
         if (bus_done)
         begin
             qreg <= bus_q;

+ 36 - 18
Verilog/modules/CPU/InstrMem.v

@@ -13,48 +13,66 @@ module InstrMem(
     output [31:0] bus_addr,
     output [31:0] bus_data,
     output        bus_we,
-    output        bus_start,
+    output reg    bus_start,
     input [31:0]  bus_q,
     input         bus_done,
+    input         bus_ready,
 
     input clear, hold
 );
 
-
 // in case of a clear mid transaction, ignore the next result and start again
 reg ignoreNext = 1'b0;
+reg [31:0] addr_prev = 32'd0;
+reg hit_prev = 1'b0;
+reg hold_reg = 1'b0;
 
-assign hit = bus_done && !ignoreNext;
-assign q =  (bus_done && !ignoreNext) ? bus_q : 32'd0;
+assign hit = (bus_done && !ignoreNext && !clear) || (hold_reg && hit_prev);
+assign q =  (hit_prev) ? bus_q : 32'd0;
 
 assign bus_addr = addr;
 assign bus_data = 32'd0;
 assign bus_we = 1'b0;
 
-assign bus_start = !bus_done && !hold;
+reg bus_start_prev = 1'b0;
 
 always @(posedge clk) 
 begin
     if (reset)
-    begin
         ignoreNext <= 1'b0;
+    else if (ignoreNext && (bus_done || bus_ready))
+        ignoreNext <= 1'b0;
+    else if (clear && (bus_start || !bus_ready))
+        ignoreNext <= 1'b1;
+end
+
+always @(posedge clk)
+begin
+    if (reset)
+    begin
+        bus_start <= 0;
+        bus_start_prev <= 0;
+        addr_prev <= 32'd0;
+        hit_prev <= 1'b0;
+        hold_reg <= 1'b0;
     end
     else
     begin
-        if (ignoreNext)
-        begin
-            if (bus_done)
-            begin
-                ignoreNext <= 1'b0;
-            end
-        end
-        else if (clear)
+        if (!hold && !clear && ((bus_done || hit) || addr == 0 || ignoreNext))
         begin
-            if (bus_start)
-            begin
-                ignoreNext <= 1'b1;
-            end
+            bus_start <= 1'b1;
         end
+        else
+            bus_start <= 1'b0;
+
+        addr_prev <= addr;
+        bus_start_prev <= bus_start;
+        hit_prev <= hit;
+
+        if (hold)
+            hold_reg <= 1'b1;
+        else
+            hold_reg <= 1'b0;
     end
 end
 

+ 66 - 0
Verilog/modules/FPGC6Simplified.v

@@ -0,0 +1,66 @@
+/*
+* Top level design of the FPGC6
+*/
+module FPGC6(
+    input           clk, // 50MHz
+    input           clk100, // 100MHz
+    input           nreset,
+    
+    //Led for debugging
+    output          led
+);
+
+//--------------------Reset&Stabilizers-----------------------
+//Reset signals
+wire nreset_stable, reset;
+
+MultiStabilizer multistabilizer (
+.clk(clk),
+.u0(nreset),
+.s0(nreset_stable)
+);
+
+assign reset = ~nreset_stable;
+
+
+// Bus
+wire [26:0] bus_addr;
+wire [31:0] bus_data;
+wire        bus_we;
+wire        bus_start;
+wire [31:0] bus_q;
+wire        bus_done;
+wire        bus_ready;
+
+MemoryUnit memoryunit(
+// Clocks
+.clk            (clk),
+.reset          (reset),
+
+// Bus
+.bus_addr       (bus_addr),
+.bus_data       (bus_data),
+.bus_we         (bus_we),
+.bus_start      (bus_start),
+.bus_q          (bus_q),
+.bus_done       (bus_done),
+.bus_ready       (bus_ready)
+);
+
+//---------------CPU----------------
+CPU cpu(
+.clk            (clk),
+.clk100         (clk100),
+.reset          (reset),
+
+// bus
+.bus_addr       (bus_addr),
+.bus_data       (bus_data),
+.bus_we         (bus_we),
+.bus_start      (bus_start),
+.bus_q          (bus_q),
+.bus_done       (bus_done),
+.bus_ready      (bus_ready)
+);
+
+endmodule

+ 88 - 0
Verilog/modules/Memory/MemoryUnitSimplified.v

@@ -0,0 +1,88 @@
+module MemoryUnit(
+    // Clocks
+    input           clk,
+    input           reset,
+
+    // Bus
+    input [26:0]    bus_addr,
+    input [31:0]    bus_data,
+    input           bus_we,
+    input           bus_start,
+    output [31:0]   bus_q,
+    output          bus_done,
+    output          bus_ready
+);
+
+reg bus_done_reg = 1'b0;
+reg bus_done_next = 1'b0;
+reg bus_ready_reg = 1'b0;
+
+//---------------------------SRAM---------------------------------
+//SRAM I/O
+wire        sram_cpu_clk;
+wire [11:0] sram_cpu_addr;
+wire [31:0] sram_cpu_d;
+wire        sram_cpu_we; 
+wire [31:0] sram_cpu_q;
+
+assign sram_cpu_addr = bus_addr;
+assign sram_cpu_d    = bus_data;
+assign sram_cpu_we   = bus_we;
+
+assign bus_q = sram_cpu_q;
+
+SRAM #(
+.WIDTH(32),
+.WORDS(4096),
+.ADDR_BITS(12),
+.LIST("/home/bart/Documents/FPGA/FPGC6/Verilog/memory/sram.list")
+)   sram(
+//CPU port
+.cpu_clk    (clk),
+.cpu_d      (sram_cpu_d),
+.cpu_addr   (sram_cpu_addr),
+.cpu_we     (sram_cpu_we),
+.cpu_q      (sram_cpu_q)
+);
+
+parameter SLOW_ADDR = 100;
+
+assign bus_done = (bus_addr < SLOW_ADDR) ? bus_start || bus_done_reg : bus_done_reg;
+assign bus_ready = bus_ready_reg;
+
+
+always @(posedge clk)
+begin
+    if (reset)
+    begin
+        bus_done_reg <= 1'b0;
+        bus_ready_reg <= 1'b0;
+        bus_done_next <= 1'b0;
+    end
+    else
+    begin
+        bus_done_reg <= 1'b0;
+        bus_ready_reg <= 1'b1;
+
+        if (bus_done_next)
+        begin
+            bus_done_next <= 1'b0;
+            bus_ready_reg <= 1'b0;
+            bus_done_reg <= 1'b1;
+        end
+        else if (bus_addr >= SLOW_ADDR)
+        begin
+            if (bus_start)
+            begin
+                bus_ready_reg <= 1'b0;
+            end
+            else if (!bus_ready_reg)
+            begin
+                bus_done_next <= 1'b1;
+                bus_ready_reg <= 1'b1;
+            end
+        end
+    end
+end
+
+endmodule

+ 38 - 0
Verilog/modules/Memory/SRAM.v

@@ -0,0 +1,38 @@
+/*
+* SRAM implementation
+*/
+module SRAM
+#(
+    parameter WIDTH = 32,
+    parameter WORDS = 4096,
+    parameter ADDR_BITS = 12,
+    parameter LIST  = "/home/bart/Documents/FPGA/FPGC6/Verilog/memory/sram.list"
+) 
+(
+  input                   cpu_clk,        
+  input      [WIDTH-1:0]  cpu_d,
+  input      [ADDR_BITS-1:0]       cpu_addr,
+  input                   cpu_we,
+  output reg [WIDTH-1:0]  cpu_q
+);
+
+reg [WIDTH-1:0] ram [0:WORDS-1]; //basically the memory cells
+
+//cpu port
+always @(posedge cpu_clk) 
+begin
+  cpu_q <= ram[cpu_addr];
+  if (cpu_we)
+  begin
+    cpu_q         <= cpu_d;
+    ram[cpu_addr] <= cpu_d;
+  end
+end
+
+//initialize VRAM
+initial 
+begin
+  $readmemb(LIST, ram);
+end
+
+endmodule

+ 118 - 301
Verilog/output/B32P.gtkw

@@ -1,376 +1,193 @@
 [*]
-[*] GTKWave Analyzer v3.3.107 (w)1999-2020 BSI
-[*] Wed Jul  6 10:46:49 2022
+[*] GTKWave Analyzer v3.3.116 (w)1999-2023 BSI
+[*] Sat Sep 21 12:22:32 2024
 [*]
 [dumpfile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/wave.vcd"
-[dumpfile_mtime] "Wed Jul  6 10:46:10 2022"
-[dumpfile_size] 689109
+[dumpfile_mtime] "Sat Aug 31 18:28:43 2024"
+[dumpfile_size] 86361
 [savefile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/B32P.gtkw"
 [timestart] 0
-[size] 1920 1027
+[size] 1920 1001
 [pos] -1 -1
-*-17.666576 932000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-[treeopen] B32P_tb.
-[treeopen] B32P_tb.cpu.
-[sst_width] 254
-[signals_width] 485
+*-7.414134 428 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] FPGC_tb.
+[treeopen] FPGC_tb.fpgc.
+[treeopen] FPGC_tb.fpgc.cpu.
+[treeopen] FPGC_tb.fpgc.memoryunit.
+[sst_width] 278
+[signals_width] 251
 [sst_expanded] 1
-[sst_vpaned_height] 307
+[sst_vpaned_height] 264
 @28
-B32P_tb.clk_SDRAM
-B32P_tb.cpu.clk
-B32P_tb.cpu.reset
+FPGC_tb.clk
+FPGC_tb.fpgc.reset
 @200
 -
--
--
--Arbiter
-@28
-B32P_tb.cpu.arbiter.clk
-@22
-B32P_tb.cpu.arbiter.addr_a[31:0]
-B32P_tb.cpu.arbiter.data_a[31:0]
+-CPU
+@24
+FPGC_tb.fpgc.cpu.pc_FE_prev[31:0]
+FPGC_tb.fpgc.cpu.pc_FE[31:0]
+FPGC_tb.fpgc.cpu.jump_addr_MEM[31:0]
 @28
-B32P_tb.cpu.arbiter.start_a
-B32P_tb.cpu.arbiter.we_a
+FPGC_tb.fpgc.cpu.instr_DE[31:0]
+FPGC_tb.fpgc.cpu.instr_EX[31:0]
+FPGC_tb.fpgc.cpu.instr_MEM[31:0]
+FPGC_tb.fpgc.cpu.instr_WB[31:0]
 @200
 -
 @28
-B32P_tb.cpu.arbiter.done_a
-B32P_tb.cpu.arbiter.busy_a
+FPGC_tb.fpgc.cpu.stall_FE
+FPGC_tb.fpgc.cpu.stall_DE
+FPGC_tb.fpgc.cpu.stall_EX
+FPGC_tb.fpgc.cpu.stall_MEM
+FPGC_tb.fpgc.cpu.stall_WB
 @200
 -
-@22
-B32P_tb.cpu.arbiter.addr_b[31:0]
-B32P_tb.cpu.arbiter.data_b[31:0]
+@29
+FPGC_tb.fpgc.cpu.flush_DE
 @28
-B32P_tb.cpu.arbiter.start_b
-B32P_tb.cpu.arbiter.we_b
+FPGC_tb.fpgc.cpu.flush_EX
+FPGC_tb.fpgc.cpu.flush_FE
 @200
 -
 @28
-B32P_tb.cpu.arbiter.done_b
-B32P_tb.cpu.arbiter.busy_b
+FPGC_tb.fpgc.cpu.datamem_busy_MEM
 @200
 -
-@22
-B32P_tb.cpu.arbiter.q[31:0]
-@200
--
--MU
-@22
-B32P_tb.mu.bus_addr[26:0]
-@24
-B32P_tb.mu.bus_data[31:0]
-B32P_tb.mu.bus_we
-B32P_tb.mu.bus_start
-@28
-B32P_tb.mu.bus_q[31:0]
+-Registers
 @24
-B32P_tb.mu.bus_done
-B32P_tb.mu.bus_done_next
+FPGC_tb.fpgc.cpu.regbank.addr_d[3:0]
+FPGC_tb.fpgc.cpu.regbank.data_d[31:0]
+FPGC_tb.fpgc.cpu.regbank.we
 @200
 -
--
-@28
-B32P_tb.mu.sreader.initDone
-B32P_tb.mu.sreader.recvDone
-B32P_tb.mu.sreader.instr[31:0]
-B32P_tb.mu.SPIflashReader_q[31:0]
-B32P_tb.mu.bus_q_wire[31:0]
-B32P_tb.mu.bus_q_wire_reg[31:0]
+@24
+FPGC_tb.fpgc.cpu.regbank.addr_a[3:0]
+FPGC_tb.fpgc.cpu.regbank.data_a[31:0]
+FPGC_tb.fpgc.cpu.regbank.addr_b[3:0]
+FPGC_tb.fpgc.cpu.regbank.data_b[31:0]
 @200
 -
--DataMem
+-SRAM
 @28
-B32P_tb.cpu.dataMem.bus_done
-B32P_tb.cpu.dataMem.bus_start
-B32P_tb.cpu.dataMem.bus_we
-B32P_tb.cpu.dataMem.busy
-@200
--
--
--
--
--SDRAM Controller
-@22
-B32P_tb.mu.sdramcontroller.state[6:0]
-@28
-B32P_tb.mu.sdramcontroller.busy
-B32P_tb.mu.sdramcontroller.initDone
+FPGC_tb.fpgc.memoryunit.sram.cpu_clk
 @24
-B32P_tb.mu.sdramcontroller.InitCounter[31:0]
+FPGC_tb.fpgc.memoryunit.sram.cpu_addr[11:0]
 @28
-B32P_tb.mu.sdramcontroller.isRefreshing
+FPGC_tb.fpgc.memoryunit.sram.cpu_we
 @24
-B32P_tb.mu.sdramcontroller.WrData[15:0]
-B32P_tb.mu.sdramcontroller.addr[23:0]
-@200
--
--
--
--
--
--
--
--
-@28
-B32P_tb.cpu.int1
-B32P_tb.cpu.int2
-B32P_tb.cpu.int3
-B32P_tb.cpu.int4
-B32P_tb.cpu.int5
-B32P_tb.cpu.int6
-B32P_tb.cpu.int7
-B32P_tb.cpu.int8
-B32P_tb.cpu.int9
-B32P_tb.cpu.int10
-@200
--
--
+FPGC_tb.fpgc.memoryunit.sram.cpu_d[31:0]
 @28
-B32P_tb.cpu.intController.int1_triggered
-B32P_tb.cpu.intController.int2_triggered
-B32P_tb.cpu.intController.int3_triggered
-B32P_tb.cpu.intController.int4_triggered
-B32P_tb.cpu.intController.int5_triggered
-B32P_tb.cpu.intController.int6_triggered
-B32P_tb.cpu.intController.int7_triggered
-B32P_tb.cpu.intController.int8_triggered
-B32P_tb.cpu.intController.int9_triggered
-@29
-B32P_tb.cpu.intController.int10_triggered
-@200
--
-@28
-B32P_tb.cpu.intController.intCPU
-@22
-B32P_tb.cpu.intController.intID[7:0]
-@28
-B32P_tb.cpu.intController.intDisabled
-B32P_tb.cpu.interruptValid
+FPGC_tb.fpgc.memoryunit.sram.cpu_q[31:0]
 @200
 -
-@28
-B32P_tb.cpu.reti_MEM
-@22
-B32P_tb.cpu.pc_FE[31:0]
-B32P_tb.cpu.pc4_FE[31:0]
-B32P_tb.cpu.pc4_DE[31:0]
-B32P_tb.cpu.pc4_EX[31:0]
-B32P_tb.cpu.pc4_MEM[31:0]
-B32P_tb.cpu.pc_FE_backup[31:0]
-B32P_tb.cpu.pc4_WB[31:0]
-@200
--
--Fetch
-@22
-B32P_tb.cpu.instrMem.addr[31:0]
-@28
-B32P_tb.cpu.instrMem.q[31:0]
-B32P_tb.cpu.clk
-B32P_tb.cpu.flush_FE
-B32P_tb.cpu.stall_FE
-@22
-B32P_tb.cpu.pc_FE[31:0]
-B32P_tb.cpu.pc4_FE[31:0]
-@28
-B32P_tb.cpu.instr_hit_FE
-@200
--
-@22
-B32P_tb.cpu.instrMem.addr[31:0]
-@28
-B32P_tb.cpu.instrMem.bus_q[31:0]
-B32P_tb.cpu.instrMem.bus_start
-B32P_tb.cpu.instrMem.bus_done
-B32P_tb.cpu.instrMem.q[31:0]
-@200
--
--
-@28
-B32P_tb.cpu.instrMem.hold
-B32P_tb.cpu.instrMem.clear
-B32P_tb.cpu.instrMem.ignoreNext
-@200
--
--Decode
-@28
-B32P_tb.cpu.clk
-B32P_tb.cpu.flush_DE
-B32P_tb.cpu.stall_DE
+-MU
 @24
-B32P_tb.cpu.pc4_DE[31:0]
-@28
-B32P_tb.cpu.instr_DE[31:0]
-@200
--
-@28
-B32P_tb.cpu.instrOP_DE[3:0]
-@420
-B32P_tb.cpu.alu_const16_EX[31:0]
+FPGC_tb.fpgc.memoryunit.clk
+FPGC_tb.fpgc.memoryunit.bus_addr[26:0]
+FPGC_tb.fpgc.memoryunit.bus_we
+FPGC_tb.fpgc.memoryunit.bus_data[31:0]
+FPGC_tb.fpgc.memoryunit.bus_start
+FPGC_tb.fpgc.memoryunit.bus_done_next
 @28
-B32P_tb.cpu.he_DE
-B32P_tb.cpu.sig_DE
-B32P_tb.cpu.alu_use_const_DE
-B32P_tb.cpu.dreg_we_DE
-B32P_tb.cpu.push_DE
-B32P_tb.cpu.pop_DE
-B32P_tb.cpu.mem_write_DE
-B32P_tb.cpu.mem_read_DE
-B32P_tb.cpu.getIntID_DE
-B32P_tb.cpu.getPC_DE
-B32P_tb.cpu.jumpc_DE
-B32P_tb.cpu.jumpr_DE
-B32P_tb.cpu.branch_DE
-B32P_tb.cpu.halt_DE
-@200
--
-@22
-B32P_tb.cpu.areg_DE[3:0]
-B32P_tb.cpu.breg_DE[3:0]
-@200
--
--Regbank
-@22
-B32P_tb.cpu.regbank.addr_a[3:0]
-@24
-B32P_tb.cpu.regbank.data_a[31:0]
-@22
-B32P_tb.cpu.regbank.addr_d[3:0]
+FPGC_tb.fpgc.memoryunit.bus_start
+FPGC_tb.fpgc.memoryunit.bus_ready_reg
 @24
-B32P_tb.cpu.regbank.data_b[31:0]
-B32P_tb.cpu.regbank.data_d[31:0]
-@28
-B32P_tb.cpu.regbank.we
+FPGC_tb.fpgc.memoryunit.bus_done
 @200
 -
--Execute
+-Instr Mem
 @28
-B32P_tb.cpu.clk
-B32P_tb.cpu.flush_EX
-B32P_tb.cpu.stall_EX
-@22
-B32P_tb.cpu.pc4_EX[31:0]
-@28
-B32P_tb.cpu.instr_EX[31:0]
-@200
--
-@28
-B32P_tb.cpu.aluOP_EX[3:0]
+FPGC_tb.fpgc.cpu.instrMem.hold
+FPGC_tb.fpgc.cpu.instrMem.hold_reg
+FPGC_tb.fpgc.cpu.instrMem.clear
 @24
-B32P_tb.cpu.alu_const16_EX[31:0]
-B32P_tb.cpu.data_a_EX[31:0]
-B32P_tb.cpu.data_b_EX[31:0]
-B32P_tb.cpu.alu_input_b_EX[31:0]
-B32P_tb.cpu.alu_result_EX[31:0]
-B32P_tb.cpu.execute_result_EX[31:0]
-B32P_tb.cpu.areg_EX[3:0]
-B32P_tb.cpu.breg_EX[3:0]
-B32P_tb.cpu.forward_a[1:0]
-B32P_tb.cpu.forward_b[1:0]
-B32P_tb.cpu.fw_data_a_EX[31:0]
-B32P_tb.cpu.fw_data_b_EX[31:0]
-@200
--
+FPGC_tb.fpgc.cpu.instrMem.ignoreNext
+FPGC_tb.fpgc.cpu.instrMem.bus_start
 @28
-B32P_tb.cpu.dreg_we_EX
-B32P_tb.cpu.push_EX
-B32P_tb.cpu.pop_EX
-B32P_tb.cpu.mem_read_EX
-B32P_tb.cpu.mem_write_EX
-B32P_tb.cpu.getIntID_EX
-B32P_tb.cpu.getPC_EX
-B32P_tb.cpu.jumpr_EX
-B32P_tb.cpu.jumpc_EX
-B32P_tb.cpu.branch_EX
-B32P_tb.cpu.halt_EX
-@200
--
--Memory
+FPGC_tb.fpgc.cpu.instrMem.bus_start_prev
+FPGC_tb.fpgc.cpu.instrMem.bus_ready
+@24
+FPGC_tb.fpgc.cpu.instrMem.bus_done
+FPGC_tb.fpgc.cpu.instrMem.hit
 @28
-B32P_tb.cpu.clk
-B32P_tb.cpu.flush_MEM
-B32P_tb.cpu.stall_MEM
+FPGC_tb.fpgc.cpu.instrMem.hit_prev
 @24
-B32P_tb.cpu.pc4_MEM[31:0]
+FPGC_tb.fpgc.cpu.instrMem.addr[31:0]
 @28
-B32P_tb.cpu.instr_MEM[31:0]
+FPGC_tb.fpgc.cpu.instrMem.bus_q[31:0]
+FPGC_tb.fpgc.cpu.instrMem.q[31:0]
 @200
 -
-@28
-B32P_tb.cpu.push_MEM
 @24
-B32P_tb.cpu.data_b_MEM[31:0]
-B32P_tb.cpu.stack.ptr[6:0]
-@28
-B32P_tb.cpu.pop_MEM
-@24
-B32P_tb.cpu.stack_q_WB[31:0]
+FPGC_tb.fpgc.cpu.forward_a[1:0]
+FPGC_tb.fpgc.cpu.forward_b[1:0]
 @200
 -
-@24
-B32P_tb.cpu.const16_MEM[31:0]
+-Data Mem
 @28
-B32P_tb.cpu.mem_write_MEM
+FPGC_tb.fpgc.cpu.dataMem.hold
+FPGC_tb.fpgc.cpu.dataMem.clear
 @24
-B32P_tb.cpu.dataMem_addr_MEM[31:0]
+FPGC_tb.fpgc.cpu.dataMem.data[31:0]
+FPGC_tb.fpgc.cpu.dataMem.we
+FPGC_tb.fpgc.cpu.dataMem.re
 @28
-B32P_tb.cpu.mem_read_MEM
+FPGC_tb.fpgc.cpu.dataMem.read_or_write_edge
 @24
-B32P_tb.cpu.dataMem.q[31:0]
-B32P_tb.cpu.data_d_WB[31:0]
+FPGC_tb.fpgc.cpu.dataMem.busy
 @200
 -
 @24
-B32P_tb.cpu.alu_result_MEM[31:0]
-@28
-B32P_tb.cpu.dreg_we_MEM
-@24
-B32P_tb.cpu.dreg_MEM[3:0]
-@200
--
-@28
-B32P_tb.cpu.halt_MEM
-B32P_tb.cpu.jumpc_MEM
-B32P_tb.cpu.jumpr_MEM
-B32P_tb.cpu.branch_MEM
-B32P_tb.cpu.reti_MEM
-B32P_tb.cpu.branch_passed_MEM
-B32P_tb.cpu.branchOP_MEM[2:0]
-@22
-B32P_tb.cpu.jump_addr_MEM[31:0]
+FPGC_tb.fpgc.cpu.dataMem.bus_start
+FPGC_tb.fpgc.cpu.dataMem.bus_we
+FPGC_tb.fpgc.cpu.dataMem.bus_addr[31:0]
+FPGC_tb.fpgc.cpu.dataMem.bus_data[31:0]
+FPGC_tb.fpgc.cpu.dataMem.bus_done
+FPGC_tb.fpgc.cpu.dataMem.q[31:0]
 @200
 -
--Write Back
-@28
-B32P_tb.cpu.clk
-B32P_tb.cpu.flush_WB
-B32P_tb.cpu.stall_WB
+-Arbiter
 @24
-B32P_tb.cpu.pc4_WB[31:0]
+FPGC_tb.fpgc.cpu.arbiter.start_a
+FPGC_tb.fpgc.cpu.arbiter.done_a
+FPGC_tb.fpgc.cpu.arbiter.addr_a[31:0]
+FPGC_tb.fpgc.cpu.arbiter.data_a[31:0]
 @28
-B32P_tb.cpu.instr_WB[31:0]
+FPGC_tb.fpgc.cpu.arbiter.ready_a
 @200
 -
 @24
-B32P_tb.cpu.dreg_WB[3:0]
-B32P_tb.cpu.data_d_WB[31:0]
+FPGC_tb.fpgc.cpu.arbiter.start_b
+FPGC_tb.fpgc.cpu.arbiter.we_b
+FPGC_tb.fpgc.cpu.arbiter.addr_b[31:0]
+FPGC_tb.fpgc.cpu.arbiter.data_b[31:0]
+FPGC_tb.fpgc.cpu.arbiter.port_b_access
 @28
-B32P_tb.cpu.dreg_we_WB
+FPGC_tb.fpgc.cpu.arbiter.ready_b
 @200
 -
 @24
-B32P_tb.cpu.stack_q_WB[31:0]
-B32P_tb.cpu.dataMem_q_WB[31:0]
-B32P_tb.cpu.alu_result_WB[31:0]
+FPGC_tb.fpgc.cpu.arbiter.state[2:0]
 @200
 -
+@24
+FPGC_tb.fpgc.cpu.arbiter.bus_start
+FPGC_tb.fpgc.cpu.arbiter.bus_we
+FPGC_tb.fpgc.cpu.arbiter.bus_addr[26:0]
+FPGC_tb.fpgc.cpu.arbiter.bus_data[31:0]
+FPGC_tb.fpgc.cpu.arbiter.bus_done
 @28
-B32P_tb.cpu.mem_read_WB
-B32P_tb.cpu.pop_WB
+FPGC_tb.fpgc.cpu.arbiter.bus_ready
 @200
 -
--
+-Stack
+@24
+FPGC_tb.fpgc.cpu.stack.useRamResult
+FPGC_tb.fpgc.cpu.stack.ramResult[31:0]
+FPGC_tb.fpgc.cpu.stack.push
+FPGC_tb.fpgc.cpu.stack.pop
+FPGC_tb.fpgc.cpu.stack.d[31:0]
+FPGC_tb.fpgc.cpu.stack.q[31:0]
 [pattern_trace] 1
 [pattern_trace] 0

+ 376 - 0
Verilog/output/B32Pold.gtkw

@@ -0,0 +1,376 @@
+[*]
+[*] GTKWave Analyzer v3.3.107 (w)1999-2020 BSI
+[*] Wed Jul  6 10:46:49 2022
+[*]
+[dumpfile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/wave.vcd"
+[dumpfile_mtime] "Wed Jul  6 10:46:10 2022"
+[dumpfile_size] 689109
+[savefile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/B32Pold.gtkw"
+[timestart] 0
+[size] 1920 1027
+[pos] -1 -1
+*-17.666576 932000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] B32P_tb.
+[treeopen] B32P_tb.cpu.
+[sst_width] 254
+[signals_width] 485
+[sst_expanded] 1
+[sst_vpaned_height] 307
+@28
+B32P_tb.clk_SDRAM
+B32P_tb.cpu.clk
+B32P_tb.cpu.reset
+@200
+-
+-
+-
+-Arbiter
+@28
+B32P_tb.cpu.arbiter.clk
+@22
+B32P_tb.cpu.arbiter.addr_a[31:0]
+B32P_tb.cpu.arbiter.data_a[31:0]
+@28
+B32P_tb.cpu.arbiter.start_a
+B32P_tb.cpu.arbiter.we_a
+@200
+-
+@28
+B32P_tb.cpu.arbiter.done_a
+B32P_tb.cpu.arbiter.busy_a
+@200
+-
+@22
+B32P_tb.cpu.arbiter.addr_b[31:0]
+B32P_tb.cpu.arbiter.data_b[31:0]
+@28
+B32P_tb.cpu.arbiter.start_b
+B32P_tb.cpu.arbiter.we_b
+@200
+-
+@28
+B32P_tb.cpu.arbiter.done_b
+B32P_tb.cpu.arbiter.busy_b
+@200
+-
+@22
+B32P_tb.cpu.arbiter.q[31:0]
+@200
+-
+-MU
+@22
+B32P_tb.mu.bus_addr[26:0]
+@24
+B32P_tb.mu.bus_data[31:0]
+B32P_tb.mu.bus_we
+B32P_tb.mu.bus_start
+@28
+B32P_tb.mu.bus_q[31:0]
+@24
+B32P_tb.mu.bus_done
+B32P_tb.mu.bus_done_next
+@200
+-
+-
+@28
+B32P_tb.mu.sreader.initDone
+B32P_tb.mu.sreader.recvDone
+B32P_tb.mu.sreader.instr[31:0]
+B32P_tb.mu.SPIflashReader_q[31:0]
+B32P_tb.mu.bus_q_wire[31:0]
+B32P_tb.mu.bus_q_wire_reg[31:0]
+@200
+-
+-DataMem
+@28
+B32P_tb.cpu.dataMem.bus_done
+B32P_tb.cpu.dataMem.bus_start
+B32P_tb.cpu.dataMem.bus_we
+B32P_tb.cpu.dataMem.busy
+@200
+-
+-
+-
+-
+-SDRAM Controller
+@22
+B32P_tb.mu.sdramcontroller.state[6:0]
+@28
+B32P_tb.mu.sdramcontroller.busy
+B32P_tb.mu.sdramcontroller.initDone
+@24
+B32P_tb.mu.sdramcontroller.InitCounter[31:0]
+@28
+B32P_tb.mu.sdramcontroller.isRefreshing
+@24
+B32P_tb.mu.sdramcontroller.WrData[15:0]
+B32P_tb.mu.sdramcontroller.addr[23:0]
+@200
+-
+-
+-
+-
+-
+-
+-
+-
+@28
+B32P_tb.cpu.int1
+B32P_tb.cpu.int2
+B32P_tb.cpu.int3
+B32P_tb.cpu.int4
+B32P_tb.cpu.int5
+B32P_tb.cpu.int6
+B32P_tb.cpu.int7
+B32P_tb.cpu.int8
+B32P_tb.cpu.int9
+B32P_tb.cpu.int10
+@200
+-
+-
+@28
+B32P_tb.cpu.intController.int1_triggered
+B32P_tb.cpu.intController.int2_triggered
+B32P_tb.cpu.intController.int3_triggered
+B32P_tb.cpu.intController.int4_triggered
+B32P_tb.cpu.intController.int5_triggered
+B32P_tb.cpu.intController.int6_triggered
+B32P_tb.cpu.intController.int7_triggered
+B32P_tb.cpu.intController.int8_triggered
+B32P_tb.cpu.intController.int9_triggered
+@29
+B32P_tb.cpu.intController.int10_triggered
+@200
+-
+@28
+B32P_tb.cpu.intController.intCPU
+@22
+B32P_tb.cpu.intController.intID[7:0]
+@28
+B32P_tb.cpu.intController.intDisabled
+B32P_tb.cpu.interruptValid
+@200
+-
+@28
+B32P_tb.cpu.reti_MEM
+@22
+B32P_tb.cpu.pc_FE[31:0]
+B32P_tb.cpu.pc4_FE[31:0]
+B32P_tb.cpu.pc4_DE[31:0]
+B32P_tb.cpu.pc4_EX[31:0]
+B32P_tb.cpu.pc4_MEM[31:0]
+B32P_tb.cpu.pc_FE_backup[31:0]
+B32P_tb.cpu.pc4_WB[31:0]
+@200
+-
+-Fetch
+@22
+B32P_tb.cpu.instrMem.addr[31:0]
+@28
+B32P_tb.cpu.instrMem.q[31:0]
+B32P_tb.cpu.clk
+B32P_tb.cpu.flush_FE
+B32P_tb.cpu.stall_FE
+@22
+B32P_tb.cpu.pc_FE[31:0]
+B32P_tb.cpu.pc4_FE[31:0]
+@28
+B32P_tb.cpu.instr_hit_FE
+@200
+-
+@22
+B32P_tb.cpu.instrMem.addr[31:0]
+@28
+B32P_tb.cpu.instrMem.bus_q[31:0]
+B32P_tb.cpu.instrMem.bus_start
+B32P_tb.cpu.instrMem.bus_done
+B32P_tb.cpu.instrMem.q[31:0]
+@200
+-
+-
+@28
+B32P_tb.cpu.instrMem.hold
+B32P_tb.cpu.instrMem.clear
+B32P_tb.cpu.instrMem.ignoreNext
+@200
+-
+-Decode
+@28
+B32P_tb.cpu.clk
+B32P_tb.cpu.flush_DE
+B32P_tb.cpu.stall_DE
+@24
+B32P_tb.cpu.pc4_DE[31:0]
+@28
+B32P_tb.cpu.instr_DE[31:0]
+@200
+-
+@28
+B32P_tb.cpu.instrOP_DE[3:0]
+@420
+B32P_tb.cpu.alu_const16_EX[31:0]
+@28
+B32P_tb.cpu.he_DE
+B32P_tb.cpu.sig_DE
+B32P_tb.cpu.alu_use_const_DE
+B32P_tb.cpu.dreg_we_DE
+B32P_tb.cpu.push_DE
+B32P_tb.cpu.pop_DE
+B32P_tb.cpu.mem_write_DE
+B32P_tb.cpu.mem_read_DE
+B32P_tb.cpu.getIntID_DE
+B32P_tb.cpu.getPC_DE
+B32P_tb.cpu.jumpc_DE
+B32P_tb.cpu.jumpr_DE
+B32P_tb.cpu.branch_DE
+B32P_tb.cpu.halt_DE
+@200
+-
+@22
+B32P_tb.cpu.areg_DE[3:0]
+B32P_tb.cpu.breg_DE[3:0]
+@200
+-
+-Regbank
+@22
+B32P_tb.cpu.regbank.addr_a[3:0]
+@24
+B32P_tb.cpu.regbank.data_a[31:0]
+@22
+B32P_tb.cpu.regbank.addr_d[3:0]
+@24
+B32P_tb.cpu.regbank.data_b[31:0]
+B32P_tb.cpu.regbank.data_d[31:0]
+@28
+B32P_tb.cpu.regbank.we
+@200
+-
+-Execute
+@28
+B32P_tb.cpu.clk
+B32P_tb.cpu.flush_EX
+B32P_tb.cpu.stall_EX
+@22
+B32P_tb.cpu.pc4_EX[31:0]
+@28
+B32P_tb.cpu.instr_EX[31:0]
+@200
+-
+@28
+B32P_tb.cpu.aluOP_EX[3:0]
+@24
+B32P_tb.cpu.alu_const16_EX[31:0]
+B32P_tb.cpu.data_a_EX[31:0]
+B32P_tb.cpu.data_b_EX[31:0]
+B32P_tb.cpu.alu_input_b_EX[31:0]
+B32P_tb.cpu.alu_result_EX[31:0]
+B32P_tb.cpu.execute_result_EX[31:0]
+B32P_tb.cpu.areg_EX[3:0]
+B32P_tb.cpu.breg_EX[3:0]
+B32P_tb.cpu.forward_a[1:0]
+B32P_tb.cpu.forward_b[1:0]
+B32P_tb.cpu.fw_data_a_EX[31:0]
+B32P_tb.cpu.fw_data_b_EX[31:0]
+@200
+-
+@28
+B32P_tb.cpu.dreg_we_EX
+B32P_tb.cpu.push_EX
+B32P_tb.cpu.pop_EX
+B32P_tb.cpu.mem_read_EX
+B32P_tb.cpu.mem_write_EX
+B32P_tb.cpu.getIntID_EX
+B32P_tb.cpu.getPC_EX
+B32P_tb.cpu.jumpr_EX
+B32P_tb.cpu.jumpc_EX
+B32P_tb.cpu.branch_EX
+B32P_tb.cpu.halt_EX
+@200
+-
+-Memory
+@28
+B32P_tb.cpu.clk
+B32P_tb.cpu.flush_MEM
+B32P_tb.cpu.stall_MEM
+@24
+B32P_tb.cpu.pc4_MEM[31:0]
+@28
+B32P_tb.cpu.instr_MEM[31:0]
+@200
+-
+@28
+B32P_tb.cpu.push_MEM
+@24
+B32P_tb.cpu.data_b_MEM[31:0]
+B32P_tb.cpu.stack.ptr[6:0]
+@28
+B32P_tb.cpu.pop_MEM
+@24
+B32P_tb.cpu.stack_q_WB[31:0]
+@200
+-
+@24
+B32P_tb.cpu.const16_MEM[31:0]
+@28
+B32P_tb.cpu.mem_write_MEM
+@24
+B32P_tb.cpu.dataMem_addr_MEM[31:0]
+@28
+B32P_tb.cpu.mem_read_MEM
+@24
+B32P_tb.cpu.dataMem.q[31:0]
+B32P_tb.cpu.data_d_WB[31:0]
+@200
+-
+@24
+B32P_tb.cpu.alu_result_MEM[31:0]
+@28
+B32P_tb.cpu.dreg_we_MEM
+@24
+B32P_tb.cpu.dreg_MEM[3:0]
+@200
+-
+@28
+B32P_tb.cpu.halt_MEM
+B32P_tb.cpu.jumpc_MEM
+B32P_tb.cpu.jumpr_MEM
+B32P_tb.cpu.branch_MEM
+B32P_tb.cpu.reti_MEM
+B32P_tb.cpu.branch_passed_MEM
+B32P_tb.cpu.branchOP_MEM[2:0]
+@22
+B32P_tb.cpu.jump_addr_MEM[31:0]
+@200
+-
+-Write Back
+@28
+B32P_tb.cpu.clk
+B32P_tb.cpu.flush_WB
+B32P_tb.cpu.stall_WB
+@24
+B32P_tb.cpu.pc4_WB[31:0]
+@28
+B32P_tb.cpu.instr_WB[31:0]
+@200
+-
+@24
+B32P_tb.cpu.dreg_WB[3:0]
+B32P_tb.cpu.data_d_WB[31:0]
+@28
+B32P_tb.cpu.dreg_we_WB
+@200
+-
+@24
+B32P_tb.cpu.stack_q_WB[31:0]
+B32P_tb.cpu.dataMem_q_WB[31:0]
+B32P_tb.cpu.alu_result_WB[31:0]
+@200
+-
+@28
+B32P_tb.cpu.mem_read_WB
+B32P_tb.cpu.pop_WB
+@200
+-
+-
+[pattern_trace] 1
+[pattern_trace] 0

+ 38 - 0
Verilog/output/bus.gtkw

@@ -0,0 +1,38 @@
+[*]
+[*] GTKWave Analyzer v3.3.116 (w)1999-2023 BSI
+[*] Sat Aug 24 20:55:07 2024
+[*]
+[dumpfile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/wave.vcd"
+[dumpfile_mtime] "Sat Aug 24 20:49:42 2024"
+[dumpfile_size] 8928
+[savefile] "/home/bart/Documents/FPGA/FPGC6/Verilog/output/bus.gtkw"
+[timestart] 0
+[size] 1545 1001
+[pos] -1 -1
+*-7.200000 1007 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] busProtocol_tb.
+[sst_width] 278
+[signals_width] 142
+[sst_expanded] 1
+[sst_vpaned_height] 297
+@28
+busProtocol_tb.clk
+busProtocol_tb.reset
+@24
+busProtocol_tb.bus_data[31:0]
+busProtocol_tb.bus_we
+@25
+busProtocol_tb.bus_addr[26:0]
+@24
+busProtocol_tb.bus_q[31:0]
+@200
+-
+@24
+busProtocol_tb.bus_start
+busProtocol_tb.bus_done
+@28
+busProtocol_tb.cpu.bus_ready
+@200
+-
+[pattern_trace] 1
+[pattern_trace] 0

+ 43 - 625
Verilog/testbench/B32P_tb.v

@@ -1,12 +1,18 @@
 /*
  * Testbench
- * Simulates the B32P CPU
+ * Simulates the CPU while using a simplified version of the rest of the system
 */
 
 // Set timescale
 `timescale 1 ns/1 ns
 
-// Include modules
+// tld
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/FPGC6Simplified.v"
+
+// other logic
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/MultiStabilizer.v"
+
+// cpu
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/CPU.v"
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/ALU.v"
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/ControlUnit.v"
@@ -17,657 +23,69 @@
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/DataMem.v"
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/Regr.v"
 `include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/IntController.v"
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/L1Icache.v"
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/L1Dcache.v"
 
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/CPU/Arbiter.v"
-
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/VRAM.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/mt48lc16m16a2.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/w25q128jv.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/SDRAMcontroller.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/SPIreader.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/ROM.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/MemoryUnit.v"
-
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/Keyboard.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/OStimer.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/UARTtx.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/UARTrx.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/SimpleSPI.v"
-`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/IO/LEDvisualizer.v"
+// memory
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/SRAM.v"
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/MemoryUnitSimplified.v"
 
 
 // Define testmodule
-module B32P_tb;
-
-//---------------CPU----------------
-// CPU I/O
-reg clk = 0;
-reg clk_SDRAM = 0;
-reg reset = 0;
-
-reg int1 = 1'b0;
-reg int2 = 1'b0;
-reg int3 = 1'b0;
-reg int4 = 1'b0;
-reg int5 = 1'b0;
-reg int6 = 1'b0;
-reg int7 = 1'b0;
-reg int8 = 1'b0;
-reg int9 = 1'b0;
-reg int10 = 1'b0;
-
-//Bus
-wire [26:0] bus_addr;
-wire [31:0] bus_data;
-wire        bus_we;
-wire        bus_start;
-wire [31:0] bus_q;
-wire        bus_done;
-
-
-
-
-//----------DEV-------------
-
-
-//---------------------------VRAM32---------------------------------
-//VRAM32 I/O
-wire        vram32_gpu_clk;
-wire [13:0] vram32_gpu_addr;
-wire [31:0] vram32_gpu_d;
-wire        vram32_gpu_we;
-wire [31:0] vram32_gpu_q;
-
-wire        vram32_cpu_clk;
-wire [13:0] vram32_cpu_addr;
-wire [31:0] vram32_cpu_d;
-wire        vram32_cpu_we; 
-wire [31:0] vram32_cpu_q;
-
-//because FSX will not write to VRAM
-assign vram32_gpu_we    = 1'b0;
-assign vram32_gpu_d     = 32'd0;
-
-VRAM #(
-.WIDTH(32), 
-.WORDS(1056), 
-.LIST("/home/bart/Documents/FPGA/FPGC5/Verilog/memory/vram32.list")
-)   vram32(
-//CPU port
-.cpu_clk    (clk),
-.cpu_d      (vram32_cpu_d),
-.cpu_addr   (vram32_cpu_addr),
-.cpu_we     (vram32_cpu_we),
-.cpu_q      (vram32_cpu_q),
-
-//GPU port
-.gpu_clk    (clkMuxOut),
-.gpu_d      (vram32_gpu_d),
-.gpu_addr   (vram32_gpu_addr),
-.gpu_we     (vram32_gpu_we),
-.gpu_q      (vram32_gpu_q)
-);
-
-
-//---------------------------VRAM322--------------------------------
-//VRAM322 I/O
-wire        vram322_gpu_clk;
-wire [13:0] vram322_gpu_addr;
-wire [31:0] vram322_gpu_d;
-wire        vram322_gpu_we;
-wire [31:0] vram322_gpu_q;
-
-//because FSX will not write to VRAM
-assign vram322_gpu_we    = 1'b0;
-assign vram322_gpu_d     = 32'd0;
-
-VRAM #(
-.WIDTH(32), 
-.WORDS(1056), 
-.LIST("/home/bart/Documents/FPGA/FPGC5/Verilog/memory/vram32.list")
-)   vram322(
-//CPU port
-.cpu_clk    (clk),
-.cpu_d      (vram32_cpu_d),
-.cpu_addr   (vram32_cpu_addr),
-.cpu_we     (vram32_cpu_we),
-.cpu_q      (),
-
-//GPU port
-.gpu_clk    (clkMuxOut),
-.gpu_d      (vram322_gpu_d),
-.gpu_addr   (vram322_gpu_addr),
-.gpu_we     (vram322_gpu_we),
-.gpu_q      (vram322_gpu_q)
-);
-
-
-//--------------------------VRAM8--------------------------------
-//VRAM8 I/O
-wire        vram8_gpu_clk;
-wire [13:0] vram8_gpu_addr;
-wire [7:0]  vram8_gpu_d;
-wire        vram8_gpu_we;
-wire [7:0]  vram8_gpu_q;
-
-wire        vram8_cpu_clk;
-wire [13:0] vram8_cpu_addr;
-wire [7:0]  vram8_cpu_d;
-wire        vram8_cpu_we;
-wire [7:0]  vram8_cpu_q;
-
-//because FSX will not write to VRAM
-assign vram8_gpu_we     = 1'b0;
-assign vram8_gpu_d      = 8'd0;
-
-VRAM #(
-.WIDTH(8), 
-.WORDS(8194), 
-.LIST("/home/bart/Documents/FPGA/FPGC5/Verilog/memory/vram8.list")
-)   vram8(
-//CPU port
-.cpu_clk    (clk),
-.cpu_d      (vram8_cpu_d),
-.cpu_addr   (vram8_cpu_addr),
-.cpu_we     (vram8_cpu_we),
-.cpu_q      (vram8_cpu_q),
-
-//GPU port
-.gpu_clk    (clkMuxOut),
-.gpu_d      (vram8_gpu_d),
-.gpu_addr   (vram8_gpu_addr),
-.gpu_we     (vram8_gpu_we),
-.gpu_q      (vram8_gpu_q)
-);
-
-
-//--------------------------VRAMSPR--------------------------------
-//VRAMSPR I/O
-wire        vramSPR_gpu_clk;
-wire [13:0] vramSPR_gpu_addr;
-wire [8:0]  vramSPR_gpu_d;
-wire        vramSPR_gpu_we;
-wire [8:0]  vramSPR_gpu_q;
+module FPGC_tb;
 
-wire        vramSPR_cpu_clk;
-wire [13:0] vramSPR_cpu_addr;
-wire [8:0]  vramSPR_cpu_d;
-wire        vramSPR_cpu_we;
-wire [8:0]  vramSPR_cpu_q;
+//Clock I/O
+reg clk;
+reg clk100;
+reg nreset;
 
-//because FSX will not write to VRAM
-assign vramSPR_gpu_we     = 1'b0;
-assign vramSPR_gpu_d      = 9'd0;
-
-VRAM #(
-.WIDTH(9), 
-.WORDS(256), 
-.LIST("/home/bart/Documents/FPGA/FPGC5/Verilog/memory/vramSPR.list")
-)   vramSPR(
-//CPU port
-.cpu_clk    (clk),
-.cpu_d      (vramSPR_cpu_d),
-.cpu_addr   (vramSPR_cpu_addr),
-.cpu_we     (vramSPR_cpu_we),
-.cpu_q      (vramSPR_cpu_q),
-
-//GPU port
-.gpu_clk    (clkMuxOut),
-.gpu_d      (vramSPR_gpu_d),
-.gpu_addr   (vramSPR_gpu_addr),
-.gpu_we     (vramSPR_gpu_we),
-.gpu_q      (vramSPR_gpu_q)
+FPGC6 fpgc (
+.clk(clk),
+.clk100(clk100),
+.nreset(nreset)
 );
 
 
-//-------------------ROM-------------------------
-//ROM I/O
-wire [8:0] rom_addr;
-wire [31:0] rom_q;
-
-
-ROM rom(
-.clk            (clk),
-.reset          (reset),
-.address        (rom_addr),
-.q              (rom_q)
-);
-
-
-
-
-//SPI0 Flash
-wire SPI0_clk;
-wire SPI0_cs; 
-wire SPI0_data; 
-wire SPI0_wp;
-wire SPI0_q;  
-wire SPI0_hold; 
-
-W25Q128JV spiFlash (
-.CLK    (SPI0_clk), 
-.DIO    (SPI0_data), 
-.CSn    (SPI0_cs), 
-.WPn    (SPI0_wp), 
-.HOLDn  (SPI0_hold), 
-.DO     (SPI0_q)
-);
-
-//SDRAM
-wire             SDRAM_CLK;     // SDRAM clock
-wire    [31 : 0] SDRAM_DQ;      // SDRAM I/O
-wire    [12 : 0] SDRAM_A;       // SDRAM Address
-wire    [1 : 0]  SDRAM_BA;      // Bank Address
-wire             SDRAM_CKE;     // Synchronous Clock Enable
-wire             SDRAM_CSn;     // CS#
-wire             SDRAM_RASn;    // RAS#
-wire             SDRAM_CASn;    // CAS#
-wire             SDRAM_WEn;     // WE#
-wire    [3 : 0]  SDRAM_DQM;     // Mask
-
-assign SDRAM_CLK = clk_SDRAM;
-
-mt48lc16m16a2 sdram1 (
-.Dq     (SDRAM_DQ[15:0]), 
-.Addr   (SDRAM_A), 
-.Ba     (SDRAM_BA), 
-.Clk    (SDRAM_CLK), 
-.Cke    (SDRAM_CKE), 
-.Cs_n   (SDRAM_CSn), 
-.Ras_n  (SDRAM_RASn), 
-.Cas_n  (SDRAM_CASn), 
-.We_n   (SDRAM_WEn), 
-.Dqm    (SDRAM_DQM[1:0])
-);
-
-mt48lc16m16a2 sdram2 (
-.Dq     (SDRAM_DQ[31:16]), 
-.Addr   (SDRAM_A), 
-.Ba     (SDRAM_BA), 
-.Clk    (SDRAM_CLK), 
-.Cke    (SDRAM_CKE), 
-.Cs_n   (SDRAM_CSn), 
-.Ras_n  (SDRAM_RASn), 
-.Cas_n  (SDRAM_CASn), 
-.We_n   (SDRAM_WEn), 
-.Dqm    (SDRAM_DQM[3:2])
-);
-
-
-//----------------SDRAM Controller------------------
-// inputs
-wire [23:0]      sdc_addr;  // address to write or to start reading from
-wire [31:0]      sdc_data;  // data to write
-wire             sdc_we;    // write enable
-wire             sdc_start; // start trigger
-
-// outputs
-wire [31:0]     sdc_q;      // memory output
-wire            sdc_done;   // output ready
-
-SDRAMcontroller sdramcontroller(
-// clock/reset inputs
-.clk        (clk_SDRAM),
-.reset      (reset),
-
-// interface inputs
-.sdc_addr   (sdc_addr),
-.sdc_data   (sdc_data),
-.sdc_we     (sdc_we),
-.sdc_start  (sdc_start),
-
-// interface outputs
-.sdc_q      (sdc_q),
-.sdc_done   (sdc_done),
-
-// SDRAM signals
-.SDRAM_CKE  (SDRAM_CKE),
-.SDRAM_CSn  (SDRAM_CSn),
-.SDRAM_WEn  (SDRAM_WEn),
-.SDRAM_CASn (SDRAM_CASn),
-.SDRAM_RASn (SDRAM_RASn),
-.SDRAM_A    (SDRAM_A),
-.SDRAM_BA   (SDRAM_BA),
-.SDRAM_DQM  (SDRAM_DQM),
-.SDRAM_DQ   (SDRAM_DQ)
-);
-
-
-//---------------CPU----------------
-//CPU I/O
-wire [26:0] PC;
-
-CPU cpu(
-.clk            (clk),
-.reset          (reset),
-
-// bus
-.bus_addr       (bus_addr),
-.bus_data       (bus_data),
-.bus_we         (bus_we),
-.bus_start      (bus_start),
-.bus_q          (bus_q),
-.bus_done       (bus_done),
-
-// sdram bus
-.sdc_addr       (sdc_addr),
-.sdc_data       (sdc_data),
-.sdc_we         (sdc_we),
-.sdc_start      (sdc_start),
-.sdc_q          (sdc_q),
-.sdc_done       (sdc_done),
-
-.int1(int1),
-.int2(int2),
-.int3(int3),
-.int4(int4),
-.int5(int5),
-.int6(int6),
-.int7(int7),
-.int8(int8),
-.int9(int9),
-.int10(int10),
-
-.PC             (PC)
-);
-
-
-
-
-//HDMI
-wire [3:0] TMDS_p;
-wire [3:0] TMDS_n;
-
-//SPI1
-wire SPI1_clk;
-wire SPI1_cs;
-wire SPI1_mosi;
-wire SPI1_miso;
-wire SPI1_rst;
-reg  SPI1_nint;
-
-//SPI2
-wire SPI2_clk;
-wire SPI2_cs;
-wire SPI2_mosi;
-wire SPI2_miso;
-wire SPI2_rst;
-reg  SPI2_nint;
-
-//SPI3
-wire SPI3_clk;
-wire SPI3_cs;
-wire SPI3_mosi;
-wire SPI3_miso;
-wire SPI3_nrst;
-reg  SPI3_int;
-
-//SPI4
-wire SPI4_clk;
-wire SPI4_cs;
-wire SPI4_mosi;
-wire SPI4_miso;
-reg  SPI4_gp;
-
-//UART0
-reg  UART0_in;
-wire UART0_out;
-reg  UART0_dtr;
-
-//UART1
-//reg  UART1_in;
-//wire UART1_out;
-
-//UART2
-reg  UART2_in;
-wire UART2_out;
-
-//PS/2
-reg PS2_clk;
-reg PS2_data;
-
-//Led
-wire led;
-
-//GPIO
-wire [3:0]  GPO;
-reg  [3:0]  GPI;
-
-//DIP Switch
-reg [3:0] DIPS;
-
-
-
-//----------------Memory Unit--------------------
-//Memory Unit I/O
-
-//Interrupt signals
-wire        OST1_int, OST2_int, OST3_int;
-wire        UART0_rx_int, UART2_rx_int;
-wire        PS2_int;
-wire        SPI0_QSPI;
-
-MemoryUnit mu(
-//clock
-.clk            (clk),
-.reset          (reset),
-
-//CPU connection (Bus)
-.bus_addr       (bus_addr),
-.bus_data       (bus_data),
-.bus_we         (bus_we),
-.bus_start      (bus_start),
-.bus_q          (bus_q),
-.bus_done       (bus_done),
-
-/********
-* MEMORY
-********/
-
-//SPI Flash / SPI0
-.SPIflash_data  (SPI0_data), 
-.SPIflash_q     (SPI0_q), 
-.SPIflash_wp    (SPI0_wp), 
-.SPIflash_hold  (SPI0_hold),
-.SPIflash_cs    (SPI0_cs), 
-.SPIflash_clk   (SPI0_clk),
-
-//VRAM32 cpu port
-.VRAM32_cpu_d       (vram32_cpu_d),
-.VRAM32_cpu_addr    (vram32_cpu_addr), 
-.VRAM32_cpu_we      (vram32_cpu_we),
-.VRAM32_cpu_q       (vram32_cpu_q),
-
-//VRAM8 cpu port
-.VRAM8_cpu_d        (vram8_cpu_d),
-.VRAM8_cpu_addr     (vram8_cpu_addr), 
-.VRAM8_cpu_we       (vram8_cpu_we),
-.VRAM8_cpu_q        (vram8_cpu_q),
-
-//VRAMspr cpu port
-.VRAMspr_cpu_d      (vramSPR_cpu_d),
-.VRAMspr_cpu_addr   (vramSPR_cpu_addr), 
-.VRAMspr_cpu_we     (vramSPR_cpu_we),
-.VRAMspr_cpu_q      (vramSPR_cpu_q),
-
-//ROM
-.ROM_addr           (rom_addr),
-.ROM_q              (rom_q),
-
-/********
-* I/O
-********/
-
-//UART0 (Main USB)
-.UART0_in           (UART0_in),
-.UART0_out          (UART0_out),
-.UART0_rx_interrupt (UART0_rx_int),
-
-//UART1 (APU)
-/*.UART1_in           (),
-.UART1_out          (),
-.UART1_rx_interrupt (),
-*/
-
-//UART2 (GP)
-.UART2_in           (UART2_in),
-.UART2_out          (UART2_out),
-.UART2_rx_interrupt (UART2_rx_int),
-
-//SPI0 (Flash)
-//declared under MEMORY
-.SPI0_QSPI      (SPI0_QSPI),
-
-//SPI1 (USB0/CH376T)
-.SPI1_clk       (SPI1_clk),
-.SPI1_cs        (SPI1_cs),
-.SPI1_mosi      (SPI1_mosi),
-.SPI1_miso      (SPI1_miso),
-.SPI1_nint      (SPI1_nint_stable),
-
-//SPI2 (USB1/CH376T)
-.SPI2_clk       (SPI2_clk),
-.SPI2_cs        (SPI2_cs),
-.SPI2_mosi      (SPI2_mosi),
-.SPI2_miso      (SPI2_miso),
-.SPI2_nint      (SPI2_nint_stable),
-
-//SPI3 (W5500)
-.SPI3_clk       (SPI3_clk),
-.SPI3_cs        (SPI3_cs),
-.SPI3_mosi      (SPI3_mosi),
-.SPI3_miso      (SPI3_miso),
-.SPI3_int       (SPI3_int_stable),
-
-//SPI4 (EXT/GP)
-.SPI4_clk       (SPI4_clk),
-.SPI4_cs        (SPI4_cs),
-.SPI4_mosi      (SPI4_mosi),
-.SPI4_miso      (SPI4_miso),
-.SPI4_GP        (SPI4_gp_stable),
-
-//GPIO (Separated GPI and GPO until GPIO module is implemented)
-.GPI        (GPI[3:0]),
-.GPO        (GPO[3:0]),
-
-//OStimers
-.OST1_int   (OST1_int),
-.OST2_int   (OST2_int),
-.OST3_int   (OST3_int),
-
-//SNESpad
-/*
-.SNES_clk   (),
-.SNES_latch (),
-.SNES_data  (),
-*/
-
-//PS/2
-.PS2_clk    (PS2_clk),
-.PS2_data   (PS2_data),
-.PS2_int    (PS2_int), //Scan code ready signal
-
-//Boot mode
-.boot_mode  (boot_mode_stable)
-);
-
-
-
 
 initial
 begin
-
-    // dump everything for GTKwave
+    //Dump everything for GTKwave
     $dumpfile("/home/bart/Documents/FPGA/FPGC6/Verilog/output/wave.vcd");
     $dumpvars;
 
-    reset = 0;
+    clk = 0;
+    nreset = 1;
 
-    //repeat(5120) #10 clk = ~clk; // 50MHz
 
-    repeat(4)
+    repeat(3)
     begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
     end
 
-    reset = 1;
+    nreset = 0;
 
-    repeat(4)
+    repeat(3)
     begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
     end
 
-    reset = 0;
+    nreset = 1;
 
-    repeat(22)
+    repeat(1000)
     begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
+        #5 clk100 = ~clk100; clk = ~clk; //50MHz
+        #5 clk100 = ~clk100; //100MHz
     end
 
-    int1 = 1'b1;
-    int2 = 1'b1;
-    int3 = 1'b1;
-    int4 = 1'b1;
-    int5 = 1'b1;
-    int6 = 1'b1;
-    int7 = 1'b1;
-    int8 = 1'b1;
-    int9 = 1'b1;
-    int10 = 1'b1;
-
-    repeat(500)
-    begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
-    end
-
-    int1 = 1'b0;
-    int2 = 1'b0;
-    int3 = 1'b0;
-    int4 = 1'b0;
-    int5 = 1'b0;
-    int6 = 1'b0;
-    int7 = 1'b0;
-    int8 = 1'b0;
-    int9 = 1'b0;
-    int10 = 1'b0;
-
-    repeat(100)
-    begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
-    end
-
-    int1 = 1'b1;
-    int2 = 1'b1;
-    int3 = 1'b1;
-    int4 = 1'b1;
-    int5 = 1'b1;
-    int6 = 1'b1;
-    int7 = 1'b1;
-    int8 = 1'b1;
-    int9 = 1'b1;
-    int10 = 1'b1;
-
-    repeat(500)
-    begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
-    end
-
-    /*
-    repeat(4096)
-    begin
-        #5 clk_SDRAM = ~clk_SDRAM; clk = ~clk; //50MHz
-        #5 clk_SDRAM = ~clk_SDRAM; //100MHz
-    end
-    */
-
-
     #1 $finish;
 end
 
-endmodule
+endmodule

+ 49 - 0
Verilog/testbench/busProtocol/cpu.v

@@ -0,0 +1,49 @@
+module CPU(
+    input clk, reset,
+    output [26:0] bus_addr,
+    output [31:0] bus_data,
+    output bus_we,
+    output reg bus_start,
+    input [31:0] bus_q,
+    input bus_done, bus_ready,
+    input clear, hold
+);
+
+reg ignoreNext;
+reg  [31:0] addr = 0;
+
+assign bus_addr = addr;
+assign bus_data = 32'd0;
+assign bus_we = 1'b0;
+
+always @(posedge clk) 
+begin
+    if (reset)
+        ignoreNext <= 1'b0;
+    else if (ignoreNext && bus_done)
+        ignoreNext <= 1'b0;
+    else if (clear && bus_start)
+        ignoreNext <= 1'b1;
+end
+
+always @(posedge clk)
+begin
+    if (reset)
+    begin
+        addr <= 0;
+        bus_start <= 0;
+    end
+    else
+    begin
+
+        if (bus_ready && !hold && !(bus_start && !bus_done))
+        begin
+            bus_start <= 1'b1;
+            addr <= addr + 1;
+        end
+        else
+            bus_start <= 1'b0;
+    end
+end
+
+endmodule

+ 86 - 0
Verilog/testbench/busProtocol/mu.v

@@ -0,0 +1,86 @@
+module MemoryUnit(
+    // Clocks
+    input           clk,
+    input           reset,
+
+    // Bus
+    input [26:0]    bus_addr,
+    input [31:0]    bus_data,
+    input           bus_we,
+    input           bus_start,
+    output [31:0]   bus_q,
+    output          bus_done,
+    output          bus_ready
+);
+
+reg bus_done_reg = 1'b0;
+reg bus_done_next = 1'b0;
+reg bus_ready_reg = 1'b0;
+
+//---------------------------SRAM---------------------------------
+//SRAM I/O
+wire        sram_cpu_clk;
+wire [11:0] sram_cpu_addr;
+wire [31:0] sram_cpu_d;
+wire        sram_cpu_we; 
+wire [31:0] sram_cpu_q;
+
+assign sram_cpu_addr = bus_addr;
+assign sram_cpu_d    = bus_data;
+assign sram_cpu_we   = bus_we;
+
+assign bus_q = sram_cpu_q;
+
+SRAM #(
+.WIDTH(32),
+.WORDS(4096),
+.ADDR_BITS(12),
+.LIST("/home/bart/Documents/FPGA/FPGC6/Verilog/memory/sram.list")
+)   sram(
+//CPU port
+.cpu_clk    (clk),
+.cpu_d      (sram_cpu_d),
+.cpu_addr   (sram_cpu_addr),
+.cpu_we     (sram_cpu_we),
+.cpu_q      (sram_cpu_q)
+);
+
+assign bus_done = (bus_addr < 8) ? bus_start : bus_done_reg;
+assign bus_ready = bus_ready_reg;
+
+
+always @(posedge clk)
+begin
+    if (reset)
+    begin
+        bus_done_reg <= 1'b0;
+        bus_ready_reg <= 1'b0;
+        bus_done_next <= 1'b0;
+    end
+    else
+    begin
+        bus_done_reg <= 1'b0;
+        bus_ready_reg <= 1'b1;
+
+        if (bus_done_next)
+        begin
+            bus_done_next <= 1'b0;
+            bus_ready_reg <= 1'b0;
+            bus_done_reg <= 1'b1;
+        end
+        else if (bus_addr >= 8)
+        begin
+            if (bus_start)
+            begin
+                bus_ready_reg <= 1'b0;
+            end
+            else if (!bus_ready_reg)
+            begin
+                bus_done_next <= 1'b1;
+                bus_ready_reg <= 1'b1;
+            end
+        end
+    end
+end
+
+endmodule

+ 98 - 0
Verilog/testbench/busProtocol_tb.v

@@ -0,0 +1,98 @@
+/*
+ * Testbench
+ * Simulates the bus protocol
+*/
+
+`timescale 1 ns/1 ns
+
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/testbench/busProtocol/cpu.v"
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/testbench/busProtocol/mu.v"
+`include "/home/bart/Documents/FPGA/FPGC6/Verilog/modules/Memory/SRAM.v"
+
+module busProtocol_tb;
+
+reg clk;
+reg reset;
+
+reg clear;
+reg hold;
+
+
+// Bus
+wire [26:0] bus_addr;
+wire [31:0] bus_data;
+wire        bus_we;
+wire        bus_start;
+wire [31:0] bus_q;
+wire        bus_done;
+
+MemoryUnit memoryunit(
+// Clocks
+.clk            (clk),
+.reset          (reset),
+
+// Bus
+.bus_addr       (bus_addr),
+.bus_data       (bus_data),
+.bus_we         (bus_we),
+.bus_start      (bus_start),
+.bus_q          (bus_q),
+.bus_done       (bus_done),
+.bus_ready       (bus_ready)
+);
+
+//---------------CPU----------------
+CPU cpu(
+.clk            (clk),
+.reset          (reset),
+
+// bus
+.bus_addr       (bus_addr),
+.bus_data       (bus_data),
+.bus_we         (bus_we),
+.bus_start      (bus_start),
+.bus_q          (bus_q),
+.bus_done       (bus_done),
+.bus_ready       (bus_ready),
+.clear          (clear),
+.hold           (hold)
+);
+
+initial
+begin
+    //Dump everything for GTKwave
+    $dumpfile("/home/bart/Documents/FPGA/FPGC6/Verilog/output/wave.vcd");
+    $dumpvars;
+
+    clk = 0;
+    reset = 0;
+    clear = 0;
+    hold = 0;
+
+
+    repeat(3)
+    begin
+        #10 clk = ~clk; //50MHz
+        #10 clk = ~clk;
+    end
+
+    reset = 1;
+
+    repeat(3)
+    begin
+        #10 clk = ~clk; //50MHz
+        #10 clk = ~clk;
+    end
+
+    reset = 0;
+
+    repeat(100)
+    begin
+        #10 clk = ~clk; //50MHz
+        #10 clk = ~clk;
+    end
+
+    #1 $finish;
+end
+
+endmodule