cpu32

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c9dfe3a22ac5ac36e379231aa94daa547043d57a
parent 28a2fb2465673e397897f70005023f101373788d
Author: Brian Swetland <swetland@frotz.net>
Date:   Sat, 18 Feb 2012 03:28:27 -0800

cpu32: more pipeline insanity

- better reset logic
- add fetch phase, move to syncram for irom
- unified i/d memory
- adjust a32 for branch targets now being pc+4+imm
- we have a branch slot now

Diffstat:
MMakefile | 2+-
Ma32.c | 4++--
Mverilog/cpu32.v | 39+++++++++++++++++++++++++++++++--------
Mverilog/testbench.v | 22++++++++++++----------
4 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ # Copyright 2012, Brian Swetland. Use at your own risk. SRC := verilog/testbench.v -SRC += verilog/ram.v verilog/syncram.v verilog/rom.v verilog/control.v +SRC += verilog/dualsyncram.v verilog/control.v SRC += verilog/cpu32.v verilog/alu.v verilog/regfile.v SRC += verilog/uart.v SRC += verilog/library.v diff --git a/a32.c b/a32.c @@ -56,7 +56,7 @@ struct fixup *fixups; void fixup_branch(const char *name, int addr, int btarget, int type) { unsigned n; - n = btarget - addr; + n = btarget - addr - 1; if (!is_signed_16(n)) { die("label '%s' at %08x is out of range of %08x\n", @@ -418,7 +418,7 @@ void printinst(char *buf, unsigned pc, unsigned instr, const char *fmt) { break; case 'r': buf = append(buf,"0x"); - buf = append_u32(buf,(pc + s16)); + buf = append_u32(buf,(pc + 4 + s16)); break; case 0: goto done; diff --git a/verilog/cpu32.v b/verilog/cpu32.v @@ -15,9 +15,18 @@ module cpu32 ( output d_data_we ); -wire [31:0] ir, pc; +reg sync_reset; -wire [31:0] next_pc, pc_plus_4; +always @(posedge clk) + if (reset) + sync_reset <= 1'b1; + else + sync_reset <= 1'b0; + +wire [31:0] pc; +reg [31:0] ir; + +wire [31:0] next_pc, pc_plus_4, next_pc0; wire [3:0] opcode, opfunc, opsela, opselb, opseld; wire [15:0] opimm16; @@ -65,12 +74,22 @@ assign ctl_adata_zero = (adata == 32'h0); register #(32) PC ( .clk(clk), - .reset(reset), - .en(!hazard_rrw), + .reset(sync_reset), + .en(1), .din(next_pc), .dout(pc) ); +assign i_addr = next_pc; + +always @(posedge clk) + if (sync_reset) begin + ir <= 32'hEEEE7777; + end else begin + if (!hazard_rrw) + ir <= i_data; + end + /* these arrive from writeback */ wire [31:0] regs_wdata; wire [3:0] regs_wsel; @@ -91,10 +110,7 @@ assign hazard1 = (((regs_wsel == opsela) | (regs_wsel == opselb)) & regs_we) & ( assign hazard2 = (((mem_wsel == opsela) | (mem_wsel == opselb)) & mem_we) & (mem_wsel != 4'b1111); assign hazard_rrw = hazard1 | hazard2; -assign i_addr = pc; -assign ir = i_data; - -assign pc_plus_4 = (pc + 32'h4); +assign pc_plus_4 = hazard_rrw ? pc : (pc + 32'h4); wire [31:0] branch_to; mux2 #(32) mux_branch_to( @@ -108,6 +124,13 @@ mux2 #(32) mux_pc_source( .sel(ctl_branch_taken), .in0(pc_plus_4), .in1(branch_to), + .out(next_pc0) + ); + +mux2 #(32) mux_next_pc( + .sel(sync_reset), + .in0(next_pc0), + .in1(32'h0), .out(next_pc) ); diff --git a/verilog/testbench.v b/verilog/testbench.v @@ -34,19 +34,21 @@ cpu32 cpu( .d_data_we(ramwe) ); -rom #(32,8) rom( - .addr(romaddr[9:2]), - .data(romdata) - ); - -syncram #(32,8) ram( +dualsyncram #(32,12) memory( .clk(clk), - .addr(ramaddr[9:2]), - .rdata(ramrdata), - .wdata(ramwdata), - .we(ramwe) + .a_raddr(romaddr[13:2]), + .a_rdata(romdata), + .a_waddr(12'b0), + .a_wdata(32'b0), + .a_we(1'b0), + .b_raddr(ramaddr[13:2]), + .b_rdata(ramrdata), + .b_waddr(ramaddr[13:2]), + .b_wdata(ramwdata), + .b_we(ramwe) ); +initial $readmemh("test.hex",memory.mem); /* wire tx;