gateware

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

commit 31cf511b4e78dc976efaf7c806265f1e2f0850f8
parent 838c1bf8f985da394032076e6aad3020ee61b3e1
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed, 28 Nov 2018 09:57:09 -0800

cpu16: conditional branches and branch with link

Diffstat:
Mhdl/cpu16.sv | 21+++++++++++++++------
Mhdl/ice40up.pcf | 1+
Mhdl/testbench.sv | 2+-
3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/hdl/cpu16.sv b/hdl/cpu16.sv @@ -34,18 +34,21 @@ reg ir_valid_next; reg [15:0]pc = 16'd0; reg [15:0]ir = 16'd0; +reg [15:0]ir_link = 16'b0; reg ir_valid = 1'b0; assign ins_rd_addr = pc_next; assign ins_rd_req = 1'b1; +wire [15:0]pc_plus_1 = pc + 16'h0001; + always_comb begin if (reset) begin pc_next = 16'h0000; - end else if (ex_do_branch_imm) begin - pc_next = ex_branch_tgt; + end else if (ex_do_branch) begin + pc_next = ex_do_branch_reg ? ex_adata : ex_branch_tgt; end else if (ins_rd_rdy) begin - pc_next = pc + 16'h0001; + pc_next = pc_plus_1; end else begin pc_next = pc; end @@ -56,6 +59,7 @@ end always_ff @(posedge clk) begin pc <= pc_next; ir <= ir_next; + ir_link <= pc_plus_1; ir_valid <= ir_valid_next; end @@ -177,15 +181,16 @@ regs16 regs( .asel(ir_asel), .bsel(do_mem_write ? ir_csel : ir_bsel), .wsel(ex_wsel), - .wreg(ex_do_wreg_alu), + .wreg(ex_do_wreg_alu | ex_do_wr_link), .adata(ex_adata), .bdata(ex_bdata), - .wdata(ex_alu_rdata) + .wdata(ex_do_wr_link ? ex_link : ex_alu_rdata) ); // ---- EXECUTE ---- reg [15:0]ex_branch_tgt = 16'b0; +reg [15:0]ex_link = 16'b0; reg [2:0]ex_alu_op = 3'b0; reg [2:0]ex_wsel = 3'b0; reg ex_do_wreg_alu = 1'b0; @@ -202,6 +207,9 @@ reg ex_do_mem_write = 1'b0; reg [15:0]ex_imm = 16'b0; +wire ex_adata_zero = (ex_adata == 16'b0); +wire ex_do_branch = ex_do_branch_reg | ex_do_branch_imm | (ex_do_branch_cond & (ex_do_branch_zero == ex_adata_zero)); + `ifdef CPU16_WITH_TRACE assign trace = { pc, @@ -226,10 +234,11 @@ assign trace = { `endif always_ff @(posedge clk) begin + ex_branch_tgt <= pc + (do_branch_imm ? ir_imm_s11 : ir_imm_s7); + ex_link <= ir_link; // for mem-read or mem-write we use the ALU for Ra + imm7 ex_alu_op <= (do_adata_zero | do_mem_read | do_mem_write) ? 3'b0 : ir_alu_op; ex_wsel <= do_wr_link ? 3'd7 : ir_csel; - ex_branch_tgt <= pc + (do_branch_imm ? ir_imm_s11 : ir_imm_s7); ex_do_wreg_alu <= do_wreg_alu; ex_do_wreg_mem <= do_wreg_mem; ex_do_adata_zero <= do_adata_zero; diff --git a/hdl/ice40up.pcf b/hdl/ice40up.pcf @@ -16,3 +16,4 @@ set_io spi_cs 16 set_io out1 3 set_io out2 4 +set_io uart_tx 28 diff --git a/hdl/testbench.sv b/hdl/testbench.sv @@ -14,7 +14,7 @@ reg burp = 1'b0; always @(posedge clk) begin count <= count + 16'd1; - burp <= (count >= 16'd0010) && (count <= 16'd0012) ? 1'b1 : 1'b0; +// burp <= (count >= 16'd0010) && (count <= 16'd0012) ? 1'b1 : 1'b0; if (count == 16'd0005) reset <= 1'b0; if (count == 16'd1000) $finish; if (cpu.ir == 16'hFFFF) begin