From e59fa1dfb25ba54ec72e3c5b58ab5ffe97472e5d Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 26 Feb 2017 20:42:07 +0300 Subject: WIP: add WISHBONE interconnect support Signed-off-by: Antony Pavlov --- picorv32.v | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/picorv32.v b/picorv32.v index e3dd708..28d7027 100644 --- a/picorv32.v +++ b/picorv32.v @@ -2547,3 +2547,205 @@ module picorv32_axi_adapter ( end endmodule + +/*************************************************************** + * picorv32_wb + ***************************************************************/ + +module picorv32_wb #( + parameter [ 0:0] ENABLE_COUNTERS = 1, + parameter [ 0:0] ENABLE_COUNTERS64 = 1, + parameter [ 0:0] ENABLE_REGS_16_31 = 1, + parameter [ 0:0] ENABLE_REGS_DUALPORT = 1, + parameter [ 0:0] TWO_STAGE_SHIFT = 1, + parameter [ 0:0] BARREL_SHIFTER = 0, + parameter [ 0:0] TWO_CYCLE_COMPARE = 0, + parameter [ 0:0] TWO_CYCLE_ALU = 0, + parameter [ 0:0] COMPRESSED_ISA = 0, + parameter [ 0:0] CATCH_MISALIGN = 1, + parameter [ 0:0] CATCH_ILLINSN = 1, + parameter [ 0:0] ENABLE_PCPI = 0, + parameter [ 0:0] ENABLE_MUL = 0, + parameter [ 0:0] ENABLE_FAST_MUL = 0, + parameter [ 0:0] ENABLE_DIV = 0, + parameter [ 0:0] ENABLE_IRQ = 0, + parameter [ 0:0] ENABLE_IRQ_QREGS = 1, + parameter [ 0:0] ENABLE_IRQ_TIMER = 1, + parameter [ 0:0] ENABLE_TRACE = 0, + parameter [ 0:0] REGS_INIT_ZERO = 0, + parameter [31:0] MASKED_IRQ = 32'h 0000_0000, + parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, + parameter [31:0] PROGADDR_RESET = 32'h 0000_0000, + parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010, + parameter [31:0] STACKADDR = 32'h ffff_ffff +) ( + output trap, + + // Wishbone interfaces + input wb_rst_i, + input wb_clk_i, + + output reg [31:0] wbm_adr_o, + output reg [31:0] wbm_dat_o, + input [31:0] wbm_dat_i, + output reg wbm_we_o, + output reg [3:0] wbm_sel_o, + output reg wbm_stb_o, + input wbm_ack_i, + output reg wbm_cyc_o, + + // Pico Co-Processor Interface (PCPI) + output pcpi_valid, + output [31:0] pcpi_insn, + output [31:0] pcpi_rs1, + output [31:0] pcpi_rs2, + input pcpi_wr, + input [31:0] pcpi_rd, + input pcpi_wait, + input pcpi_ready, + + // IRQ interface + input [31:0] irq, + output [31:0] eoi, + + // Trace Interface + output trace_valid, + output [35:0] trace_data +); + wire mem_valid; + wire [31:0] mem_addr; + wire [31:0] mem_wdata; + wire [ 3:0] mem_wstrb; + wire mem_instr; + reg mem_ready; + reg [31:0] mem_rdata; + + wire clk; + wire resetn; + + assign clk = wb_clk_i; + assign resetn = ~wb_rst_i; + + picorv32 #( + .ENABLE_COUNTERS (ENABLE_COUNTERS ), + .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ), + .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ), + .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT), + .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ), + .BARREL_SHIFTER (BARREL_SHIFTER ), + .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ), + .TWO_CYCLE_ALU (TWO_CYCLE_ALU ), + .COMPRESSED_ISA (COMPRESSED_ISA ), + .CATCH_MISALIGN (CATCH_MISALIGN ), + .CATCH_ILLINSN (CATCH_ILLINSN ), + .ENABLE_PCPI (ENABLE_PCPI ), + .ENABLE_MUL (ENABLE_MUL ), + .ENABLE_FAST_MUL (ENABLE_FAST_MUL ), + .ENABLE_DIV (ENABLE_DIV ), + .ENABLE_IRQ (ENABLE_IRQ ), + .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ), + .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ), + .ENABLE_TRACE (ENABLE_TRACE ), + .REGS_INIT_ZERO (REGS_INIT_ZERO ), + .MASKED_IRQ (MASKED_IRQ ), + .LATCHED_IRQ (LATCHED_IRQ ), + .PROGADDR_RESET (PROGADDR_RESET ), + .PROGADDR_IRQ (PROGADDR_IRQ ), + .STACKADDR (STACKADDR ) + ) picorv32_core ( + .clk (clk ), + .resetn (resetn), + .trap (trap ), + + .mem_valid(mem_valid), + .mem_addr (mem_addr ), + .mem_wdata(mem_wdata), + .mem_wstrb(mem_wstrb), + .mem_instr(mem_instr), + .mem_ready(mem_ready), + .mem_rdata(mem_rdata), + + .pcpi_valid(pcpi_valid), + .pcpi_insn (pcpi_insn ), + .pcpi_rs1 (pcpi_rs1 ), + .pcpi_rs2 (pcpi_rs2 ), + .pcpi_wr (pcpi_wr ), + .pcpi_rd (pcpi_rd ), + .pcpi_wait (pcpi_wait ), + .pcpi_ready(pcpi_ready), + + .irq(irq), + .eoi(eoi), + + .trace_valid(trace_valid), + .trace_data (trace_data) + ); + + localparam IDLE = 2'b00; + localparam WBSTART = 2'b01; + localparam WBEND = 2'b10; + + reg [1:0] state; + + wire we; + assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]); + + always @(posedge wb_clk_i) + if (wb_rst_i) + begin + wbm_adr_o <= 0; + wbm_dat_o <= 0; + wbm_we_o <= 0; + wbm_sel_o <= 0; + wbm_stb_o <= 0; + wbm_cyc_o <= 0; + state <= IDLE; + end + else + begin + case (state) + IDLE: + if (mem_valid) + begin + wbm_adr_o <= mem_addr; + wbm_dat_o <= mem_wdata; + wbm_we_o <= we; + wbm_sel_o <= mem_wstrb; + + wbm_stb_o <= 1'b1; + wbm_cyc_o <= 1'b1; + state <= WBSTART; + end + else + begin + mem_ready <= 1'b0; + + wbm_stb_o <= 1'b0; + wbm_cyc_o <= 1'b0; + wbm_we_o <= 1'b0; + end + WBSTART: + if (wbm_ack_i) + begin + mem_rdata <= wbm_dat_i; + mem_ready <= 1'b1; + + state <= WBEND; + + wbm_stb_o <= 1'b0; + wbm_cyc_o <= 1'b0; + wbm_we_o <= 1'b0; + end + + WBEND: + begin + mem_ready <= 1'b0; + + state <= IDLE; + end + + default: + state <= IDLE; + endcase + end +endmodule -- cgit From a25597532d5af466a280e7c068dfae3ba362af44 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sat, 11 Mar 2017 23:55:14 +0300 Subject: WIP: add WISHBONE testbench Signed-off-by: Antony Pavlov --- .gitignore | 2 + Makefile | 16 ++- testbench_wb.v | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 testbench_wb.v diff --git a/.gitignore b/.gitignore index 7337cd8..b7b515e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ /riscv-gnu-toolchain-riscv32im /riscv-gnu-toolchain-riscv32imc /testbench.vvp +/testbench_wb.vvp +/testbench_wb.vcd /testbench_sp.vvp /testbench_synth.vvp /testbench.gtkw diff --git a/Makefile b/Makefile index 8e51ca8..5f93820 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,12 @@ test: testbench.vvp firmware/firmware.hex test_vcd: testbench.vvp firmware/firmware.hex vvp -N $< +vcd +trace +noerror +test_wb: testbench_wb.vvp firmware/firmware.hex + vvp -N $< + +test_wb_vcd: testbench_wb.vvp firmware/firmware.hex + vvp -N $< +vcd +trace +noerror + check: check-yices check-%: check.smt2 @@ -41,6 +47,10 @@ testbench.vvp: testbench.v picorv32.v iverilog -o testbench.vvp $(subst C,-DCOMPRESSED_ISA,$(COMPRESSED_ISA)) -DRISCV_FORMAL testbench.v picorv32.v chmod -x testbench.vvp +testbench_wb.vvp: testbench_wb.v picorv32.v + iverilog -o $@ $(subst C,-DCOMPRESSED_ISA,$(COMPRESSED_ISA)) -DRISCV_FORMAL $^ + chmod -x $@ + testbench_sp.vvp: testbench.v picorv32.v iverilog -o testbench_sp.vvp $(subst C,-DCOMPRESSED_ISA,$(COMPRESSED_ISA)) -DRISCV_FORMAL -DSP_TEST testbench.v picorv32.v chmod -x testbench_sp.vvp @@ -131,7 +141,7 @@ clean: riscv-gnu-toolchain-riscv32im riscv-gnu-toolchain-riscv32imc rm -vrf $(FIRMWARE_OBJS) $(TEST_OBJS) check.smt2 check.vcd synth.v synth.log \ firmware/firmware.elf firmware/firmware.bin firmware/firmware.hex firmware/firmware.map \ - testbench.vvp testbench_sp.vvp testbench_synth.vvp testbench.vcd testbench.trace - -.PHONY: test test_vcd test_sp test_axi test_synth download-tools build-tools toc clean + testbench.vvp testbench_sp.vvp testbench_synth.vvp \ + testbench_wb.vvp testbench.vcd testbench.trace +.PHONY: test test_vcd test_sp test_axi test_wb test_wb_vcd test_synth download-tools build-tools toc clean diff --git a/testbench_wb.v b/testbench_wb.v new file mode 100644 index 0000000..eee3040 --- /dev/null +++ b/testbench_wb.v @@ -0,0 +1,346 @@ +`timescale 1 ns / 1 ps + +`ifndef VERILATOR +module testbench #( + parameter VERBOSE = 0 +); + reg clk = 1; + reg resetn = 1; + wire trap; + + always #5 clk = ~clk; + + initial begin + repeat (100) @(posedge clk); + resetn <= 0; + end + + initial begin + if ($test$plusargs("vcd")) begin + $dumpfile("testbench_wb.vcd"); + $dumpvars(0, testbench); + end + repeat (1000000) @(posedge clk); + $display("TIMEOUT"); + $finish; + end + + wire trace_valid; + wire [35:0] trace_data; + integer trace_file; + + initial begin + if ($test$plusargs("trace")) begin + trace_file = $fopen("testbench.trace", "w"); + repeat (10) @(posedge clk); + while (!trap) begin + @(posedge clk); + if (trace_valid) + $fwrite(trace_file, "%x\n", trace_data); + end + $fclose(trace_file); + $display("Finished writing testbench.trace."); + end + end + + picorv32_wrapper #( + .VERBOSE (VERBOSE) + ) top ( + .wb_clk(clk), + .wb_rst(resetn), + .trap(trap), + .trace_valid(trace_valid), + .trace_data(trace_data) + ); +endmodule +`endif + +module picorv32_wrapper #( + parameter BOOTROM_MEMFILE = "", + parameter BOOTROM_MEMDEPTH = 16384 * 4, + parameter VERBOSE = 0 +) ( + input wb_clk, + input wb_rst, + output trap, + output trace_valid, + output [35:0] trace_data +); + wire tests_passed; + reg [31:0] irq; + + always @* begin + irq = 0; + irq[4] = &uut.picorv32_core.count_cycle[12:0]; + irq[5] = &uut.picorv32_core.count_cycle[15:0]; + end + +wire [31:0] wb_m2s_adr; +wire [31:0] wb_m2s_dat; +wire [3:0] wb_m2s_sel; +wire wb_m2s_we; +wire wb_m2s_cyc; +wire wb_m2s_stb; +//wire [2:0] wb_m2s_cti; +reg [2:0] wb_m2s_cti = 3'b000; +wire [1:0] wb_m2s_bte; +wire [31:0] wb_s2m_dat; +wire wb_s2m_ack; +wire wb_s2m_err; +wire wb_s2m_rty; + + wb_ram #( + .depth (16384 * 4), + .memfile ("firmware/firmware.hex"), + .VERBOSE (VERBOSE) + ) + ram (// Wishbone interface + .wb_clk_i(wb_clk), + .wb_rst_i(wb_rst), + + .wb_adr_i(wb_m2s_adr), + .wb_dat_i(wb_m2s_dat), + .wb_stb_i(wb_m2s_stb), + .wb_cyc_i(wb_m2s_cyc), + .wb_dat_o(wb_s2m_dat), + .wb_ack_o(wb_s2m_ack), + .wb_sel_i(wb_m2s_sel), + .wb_cti_i(wb_m2s_cti), + .wb_bte_i(wb_m2s_bte), + .wb_we_i(wb_m2s_we), + .wb_err_o(), + + .tests_passed(tests_passed) + ); + + picorv32_wb #( +`ifndef SYNTH_TEST +`ifdef SP_TEST + .ENABLE_REGS_DUALPORT(0), +`endif +`ifdef COMPRESSED_ISA + .COMPRESSED_ISA(1), +`endif + .ENABLE_MUL(1), + .ENABLE_DIV(1), + .ENABLE_IRQ(1), + .ENABLE_TRACE(1) +`endif + ) uut ( + .trap (trap), + .irq (irq), + .trace_valid (trace_valid), + .trace_data (trace_data), + + .wb_clk_i(wb_clk), + .wb_rst_i(wb_rst), + + .wbm_adr_o(wb_m2s_adr), + .wbm_dat_i(wb_s2m_dat), + .wbm_stb_o(wb_m2s_stb), + .wbm_ack_i(wb_s2m_ack), + .wbm_cyc_o(wb_m2s_cyc), + .wbm_dat_o(wb_m2s_dat), + .wbm_we_o(wb_m2s_we), + .wbm_sel_o(wb_m2s_sel) + ); + + integer cycle_counter; + always @(posedge wb_clk) begin + cycle_counter <= !wb_rst ? cycle_counter + 1 : 0; + if (!wb_rst && trap) begin +`ifndef VERILATOR + repeat (10) @(posedge wb_clk); +`endif + $display("TRAP after %1d clock cycles", cycle_counter); + if (tests_passed) begin + $display("ALL TESTS PASSED."); + $finish; + end else begin + $display("ERROR!"); + if ($test$plusargs("noerror")) + $finish; + $stop; + end + end + end +endmodule + +module wb_ram + #(//Wishbone parameters + parameter dw = 32, + //Memory parameters + parameter depth = 256, + parameter aw = 32, + parameter memfile = "", + parameter VERBOSE = 0 + ) + ( + input wb_clk_i, + input wb_rst_i, + + input [aw-1:0] wb_adr_i, + input [dw-1:0] wb_dat_i, + input [3:0] wb_sel_i, + input wb_we_i, + input [1:0] wb_bte_i, + input [2:0] wb_cti_i, + input wb_cyc_i, + input wb_stb_i, + + output reg wb_ack_o, + output wb_err_o, + output reg [dw-1:0] wb_dat_o, + + output reg tests_passed + ); + + localparam CLASSIC_CYCLE = 1'b0; + localparam BURST_CYCLE = 1'b1; + + localparam READ = 1'b0; + localparam WRITE = 1'b1; + + localparam [2:0] + CTI_CLASSIC = 3'b000, + CTI_CONST_BURST = 3'b001, + CTI_INC_BURST = 3'b010, + CTI_END_OF_BURST = 3'b111; + + localparam [1:0] + BTE_LINEAR = 2'd0, + BTE_WRAP_4 = 2'd1, + BTE_WRAP_8 = 2'd2, + BTE_WRAP_16 = 2'd3; + + function wb_is_last; + input [2:0] cti; + begin + case (cti) + CTI_CLASSIC : wb_is_last = 1'b1; + CTI_CONST_BURST : wb_is_last = 1'b0; + CTI_INC_BURST : wb_is_last = 1'b0; + CTI_END_OF_BURST : wb_is_last = 1'b1; + default : $display("%d : Illegal Wishbone B3 cycle type (%b)", $time, cti); + endcase + end + endfunction + + function [31:0] wb_next_adr; + input [31:0] adr_i; + input [2:0] cti_i; + input [2:0] bte_i; + input integer dw; + + reg [31:0] adr; + integer shift; + begin + shift = $clog2(dw/8); + adr = adr_i >> shift; + if (cti_i == CTI_INC_BURST) + case (bte_i) + BTE_LINEAR : adr = adr + 1; + BTE_WRAP_4 : adr = {adr[31:2], adr[1:0]+2'd1}; + BTE_WRAP_8 : adr = {adr[31:3], adr[2:0]+3'd1}; + BTE_WRAP_16 : adr = {adr[31:4], adr[3:0]+4'd1}; + endcase // case (burst_type_i) + + wb_next_adr = adr << shift; + end +endfunction + + reg verbose; + initial verbose = $test$plusargs("verbose") || VERBOSE; + + initial tests_passed = 0; + + reg [aw-1:0] adr_r; + wire [aw-1:0] next_adr; + wire valid = wb_cyc_i & wb_stb_i; + reg valid_r; + reg is_last_r; + + always @(posedge wb_clk_i) + is_last_r <= wb_is_last(wb_cti_i); + + wire new_cycle = (valid & !valid_r) | is_last_r; + + assign next_adr = wb_next_adr(adr_r, wb_cti_i, wb_bte_i, dw); + + wire [aw-1:0] adr = new_cycle ? wb_adr_i : next_adr; + + always @(posedge wb_clk_i) + begin + adr_r <= adr; + valid_r <= valid; + // Ack generation + wb_ack_o <= valid & (!((wb_cti_i == 3'b000) | (wb_cti_i == 3'b111)) | !wb_ack_o); + if (wb_rst_i) + begin + adr_r <= {aw{1'b0}}; + valid_r <= 1'b0; + wb_ack_o <= 1'b0; + end + end + + wire ram_we = wb_we_i & valid & wb_ack_o; + + assign wb_err_o = 1'b0; + + wire [aw-1:0] waddr = adr_r[aw-1:2]; + wire [aw-1:0] raddr = adr[aw-1:2]; + wire [3:0] we = {4{ram_we}} & wb_sel_i; + + wire [$clog2(depth/4)-1:0] raddr2 = raddr[$clog2(depth/4)-1:0]; + wire [$clog2(depth/4)-1:0] waddr2 = waddr[$clog2(depth/4)-1:0]; + + reg [31:0] mem [0:depth/4-1] /* verilator public */; + + always @(posedge wb_clk_i) begin + if (adr_r[aw-1:0] == 32'h1000_0000 && wb_stb_i && !wb_ack_o) + begin + $write("%c", wb_dat_i[7:0]); + end else + if (adr_r[aw-1:0] == 32'h2000_0000 && wb_stb_i && !wb_ack_o) begin + if (wb_dat_i[31:0] == 123456789) + tests_passed = 1; + end + end + + always @(posedge wb_clk_i) begin + + if (waddr2 < 64 * 1024 / 4) + begin + if (we[0]) + mem[waddr2][7:0] <= wb_dat_i[7:0]; + + if (we[1]) + mem[waddr2][15:8] <= wb_dat_i[15:8]; + + if (we[2]) + mem[waddr2][23:16] <= wb_dat_i[23:16]; + + if (we[3]) + mem[waddr2][31:24] <= wb_dat_i[31:24]; + + if (ram_we) + if (verbose) + $display("WR: ADDR=%08x DATA=%08x STRB=%04b", + adr_r, wb_dat_i, we); + end + + if (valid & wb_ack_o & !ram_we) + if (verbose) + $display("RD: ADDR=%08x DATA=%08x%s", adr_r, mem[raddr2], 0 ? " INSN" : ""); + + wb_dat_o <= mem[raddr2]; + end + + generate + initial + if (memfile != "") begin + $readmemh(memfile, mem); + end + endgenerate + +endmodule -- cgit From 3495604877d8e0cabd9c583a9dc7805803b3c83c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 14 Mar 2017 11:51:09 +0100 Subject: Fix indenting in wishbone code --- picorv32.v | 99 ++++++++++++++++------------------ testbench_wb.v | 164 +++++++++++++++++++++++++++------------------------------ 2 files changed, 124 insertions(+), 139 deletions(-) diff --git a/picorv32.v b/picorv32.v index 28d7027..862d8b5 100644 --- a/picorv32.v +++ b/picorv32.v @@ -2690,62 +2690,55 @@ module picorv32_wb #( wire we; assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]); - always @(posedge wb_clk_i) - if (wb_rst_i) - begin - wbm_adr_o <= 0; - wbm_dat_o <= 0; - wbm_we_o <= 0; - wbm_sel_o <= 0; - wbm_stb_o <= 0; - wbm_cyc_o <= 0; - state <= IDLE; - end - else - begin - case (state) - IDLE: - if (mem_valid) - begin - wbm_adr_o <= mem_addr; - wbm_dat_o <= mem_wdata; - wbm_we_o <= we; - wbm_sel_o <= mem_wstrb; - - wbm_stb_o <= 1'b1; - wbm_cyc_o <= 1'b1; - state <= WBSTART; - end - else - begin - mem_ready <= 1'b0; - - wbm_stb_o <= 1'b0; - wbm_cyc_o <= 1'b0; - wbm_we_o <= 1'b0; - end - WBSTART: - if (wbm_ack_i) - begin - mem_rdata <= wbm_dat_i; - mem_ready <= 1'b1; - - state <= WBEND; + always @(posedge wb_clk_i) begin + if (wb_rst_i) begin + wbm_adr_o <= 0; + wbm_dat_o <= 0; + wbm_we_o <= 0; + wbm_sel_o <= 0; + wbm_stb_o <= 0; + wbm_cyc_o <= 0; + state <= IDLE; + end else begin + case (state) + IDLE: begin + if (mem_valid) begin + wbm_adr_o <= mem_addr; + wbm_dat_o <= mem_wdata; + wbm_we_o <= we; + wbm_sel_o <= mem_wstrb; + + wbm_stb_o <= 1'b1; + wbm_cyc_o <= 1'b1; + state <= WBSTART; + end else begin + mem_ready <= 1'b0; - wbm_stb_o <= 1'b0; - wbm_cyc_o <= 1'b0; - wbm_we_o <= 1'b0; - end + wbm_stb_o <= 1'b0; + wbm_cyc_o <= 1'b0; + wbm_we_o <= 1'b0; + end + end + WBSTART:begin + if (wbm_ack_i) begin + mem_rdata <= wbm_dat_i; + mem_ready <= 1'b1; - WBEND: - begin - mem_ready <= 1'b0; + state <= WBEND; - state <= IDLE; - end + wbm_stb_o <= 1'b0; + wbm_cyc_o <= 1'b0; + wbm_we_o <= 1'b0; + end + end + WBEND: begin + mem_ready <= 1'b0; - default: - state <= IDLE; - endcase + state <= IDLE; + end + default: + state <= IDLE; + endcase + end end endmodule diff --git a/testbench_wb.v b/testbench_wb.v index eee3040..a613e50 100644 --- a/testbench_wb.v +++ b/testbench_wb.v @@ -75,26 +75,25 @@ module picorv32_wrapper #( irq[5] = &uut.picorv32_core.count_cycle[15:0]; end -wire [31:0] wb_m2s_adr; -wire [31:0] wb_m2s_dat; -wire [3:0] wb_m2s_sel; -wire wb_m2s_we; -wire wb_m2s_cyc; -wire wb_m2s_stb; -//wire [2:0] wb_m2s_cti; -reg [2:0] wb_m2s_cti = 3'b000; -wire [1:0] wb_m2s_bte; -wire [31:0] wb_s2m_dat; -wire wb_s2m_ack; -wire wb_s2m_err; -wire wb_s2m_rty; + wire [31:0] wb_m2s_adr; + wire [31:0] wb_m2s_dat; + wire [3:0] wb_m2s_sel; + wire wb_m2s_we; + wire wb_m2s_cyc; + wire wb_m2s_stb; + //wire [2:0] wb_m2s_cti; + reg [2:0] wb_m2s_cti = 3'b000; + wire [1:0] wb_m2s_bte; + wire [31:0] wb_s2m_dat; + wire wb_s2m_ack; + wire wb_s2m_err; + wire wb_s2m_rty; wb_ram #( .depth (16384 * 4), .memfile ("firmware/firmware.hex"), .VERBOSE (VERBOSE) - ) - ram (// Wishbone interface + ) ram ( // Wishbone interface .wb_clk_i(wb_clk), .wb_rst_i(wb_rst), @@ -111,7 +110,7 @@ wire wb_s2m_rty; .wb_err_o(), .tests_passed(tests_passed) - ); + ); picorv32_wb #( `ifndef SYNTH_TEST @@ -166,34 +165,33 @@ wire wb_s2m_rty; end endmodule -module wb_ram - #(//Wishbone parameters - parameter dw = 32, - //Memory parameters - parameter depth = 256, - parameter aw = 32, - parameter memfile = "", - parameter VERBOSE = 0 - ) - ( - input wb_clk_i, - input wb_rst_i, - - input [aw-1:0] wb_adr_i, - input [dw-1:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input [1:0] wb_bte_i, - input [2:0] wb_cti_i, - input wb_cyc_i, - input wb_stb_i, - - output reg wb_ack_o, - output wb_err_o, - output reg [dw-1:0] wb_dat_o, - - output reg tests_passed - ); +module wb_ram #( + //Wishbone parameters + parameter dw = 32, + //Memory parameters + parameter depth = 256, + parameter aw = 32, + parameter memfile = "", + parameter VERBOSE = 0 +) ( + input wb_clk_i, + input wb_rst_i, + + input [aw-1:0] wb_adr_i, + input [dw-1:0] wb_dat_i, + input [3:0] wb_sel_i, + input wb_we_i, + input [1:0] wb_bte_i, + input [2:0] wb_cti_i, + input wb_cyc_i, + input wb_stb_i, + + output reg wb_ack_o, + output wb_err_o, + output reg [dw-1:0] wb_dat_o, + + output reg tests_passed +); localparam CLASSIC_CYCLE = 1'b0; localparam BURST_CYCLE = 1'b1; @@ -214,40 +212,40 @@ module wb_ram BTE_WRAP_16 = 2'd3; function wb_is_last; - input [2:0] cti; - begin - case (cti) - CTI_CLASSIC : wb_is_last = 1'b1; - CTI_CONST_BURST : wb_is_last = 1'b0; - CTI_INC_BURST : wb_is_last = 1'b0; - CTI_END_OF_BURST : wb_is_last = 1'b1; - default : $display("%d : Illegal Wishbone B3 cycle type (%b)", $time, cti); - endcase - end + input [2:0] cti; + begin + case (cti) + CTI_CLASSIC : wb_is_last = 1'b1; + CTI_CONST_BURST : wb_is_last = 1'b0; + CTI_INC_BURST : wb_is_last = 1'b0; + CTI_END_OF_BURST : wb_is_last = 1'b1; + default : $display("%d : Illegal Wishbone B3 cycle type (%b)", $time, cti); + endcase + end endfunction function [31:0] wb_next_adr; - input [31:0] adr_i; - input [2:0] cti_i; - input [2:0] bte_i; - input integer dw; - - reg [31:0] adr; - integer shift; - begin - shift = $clog2(dw/8); - adr = adr_i >> shift; - if (cti_i == CTI_INC_BURST) - case (bte_i) - BTE_LINEAR : adr = adr + 1; - BTE_WRAP_4 : adr = {adr[31:2], adr[1:0]+2'd1}; - BTE_WRAP_8 : adr = {adr[31:3], adr[2:0]+3'd1}; - BTE_WRAP_16 : adr = {adr[31:4], adr[3:0]+4'd1}; - endcase // case (burst_type_i) - - wb_next_adr = adr << shift; - end -endfunction + input [31:0] adr_i; + input [2:0] cti_i; + input [2:0] bte_i; + input integer dw; + + reg [31:0] adr; + integer shift; + begin + shift = $clog2(dw/8); + adr = adr_i >> shift; + if (cti_i == CTI_INC_BURST) + case (bte_i) + BTE_LINEAR : adr = adr + 1; + BTE_WRAP_4 : adr = {adr[31:2], adr[1:0]+2'd1}; + BTE_WRAP_8 : adr = {adr[31:3], adr[2:0]+3'd1}; + BTE_WRAP_16 : adr = {adr[31:4], adr[3:0]+4'd1}; + endcase // case (burst_type_i) + + wb_next_adr = adr << shift; + end + endfunction reg verbose; initial verbose = $test$plusargs("verbose") || VERBOSE; @@ -269,8 +267,7 @@ endfunction wire [aw-1:0] adr = new_cycle ? wb_adr_i : next_adr; - always @(posedge wb_clk_i) - begin + always @(posedge wb_clk_i) begin adr_r <= adr; valid_r <= valid; // Ack generation @@ -308,9 +305,7 @@ endfunction end always @(posedge wb_clk_i) begin - - if (waddr2 < 64 * 1024 / 4) - begin + if (waddr2 < 64 * 1024 / 4) begin if (we[0]) mem[waddr2][7:0] <= wb_dat_i[7:0]; @@ -336,11 +331,8 @@ endfunction wb_dat_o <= mem[raddr2]; end - generate - initial - if (memfile != "") begin + initial begin + if (memfile != "") $readmemh(memfile, mem); - end - endgenerate - + end endmodule -- cgit