diff --git a/Makefile b/Makefile index 2a1f281..d48ce72 100644 --- a/Makefile +++ b/Makefile @@ -55,12 +55,15 @@ check.smt2: picorv32.v synth.v: picorv32.v scripts/yosys/synth_sim.ys yosys -qv3 -l synth.log scripts/yosys/synth_sim.ys -firmware/firmware.hex: firmware/firmware.bin firmware/makehex.py - $(PYTHON) firmware/makehex.py $< 32768 > $@ +# firmware/firmware.hex: firmware/firmware.bin firmware/makehex.py +# $(PYTHON) firmware/makehex.py $< 32768 > $@ -firmware/firmware.bin: firmware/firmware.elf - $(TOOLCHAIN_PREFIX)objcopy -O binary $< $@ - chmod -x $@ +firmware/firmware.hex: firmware/firmware.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + +# firmware/firmware.bin: firmware/firmware.elf +# $(TOOLCHAIN_PREFIX)objcopy -O binary $< $@ +# chmod -x $@ firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds $(TOOLCHAIN_PREFIX)gcc -Os -mabi=ilp32 -march=rv32im$(subst C,c,$(COMPRESSED_ISA)) -ffreestanding -nostdlib -o $@ \ diff --git a/picorv32.v b/picorv32.v index 987d617..42c6094 100644 --- a/picorv32.v +++ b/picorv32.v @@ -2252,6 +2252,7 @@ module picorv32_wb #( parameter [31:0] STACKADDR = 32'h ffff_ffff ) ( output trap, + output reg exit, // Wishbone interfaces input wb_rst_i, @@ -2293,8 +2294,16 @@ module picorv32_wb #( reg mem_ready; reg [31:0] mem_rdata; + wire mem_la_read; + wire mem_la_write; + wire [31:0] mem_la_addr; + wire [31:0] mem_la_wdata; + wire [3:0] mem_la_wstrb; + + wire clk; wire resetn; + initial exit = 0; assign clk = wb_clk_i; assign resetn = ~wb_rst_i; @@ -2330,23 +2339,19 @@ module picorv32_wb #( .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), + .mem_valid (mem_valid ), + .mem_instr (mem_instr ), + .mem_ready (mem_ready ), + .mem_addr (mem_addr ), + .mem_wdata (mem_wdata ), + .mem_wstrb (mem_wstrb ), + .mem_rdata (mem_rdata ), + .mem_la_read (mem_la_read ), + .mem_la_write(mem_la_write), + .mem_la_addr (mem_la_addr ), + .mem_la_wdata(mem_la_wdata), + .mem_la_wstrb(mem_la_wstrb), .irq(irq), .eoi(eoi), @@ -2354,63 +2359,34 @@ module picorv32_wb #( .trace_data (trace_data) ); - localparam IDLE = 2'b00; - localparam WBSTART = 2'b01; - localparam WBEND = 2'b10; - reg [1:0] state; + reg [7:0] memory [0:256*1024-1]; - wire we; - assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]); + assign mem_ready = 1; - 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 + always @(posedge clk) begin + mem_rdata[ 7: 0] <= mem_la_read ? memory[mem_la_addr + 0] : 'bx; + mem_rdata[15: 8] <= mem_la_read ? memory[mem_la_addr + 1] : 'bx; + mem_rdata[23:16] <= mem_la_read ? memory[mem_la_addr + 2] : 'bx; + mem_rdata[31:24] <= mem_la_read ? memory[mem_la_addr + 3] : 'bx; + if (mem_la_write) begin + case (mem_la_addr) + 32'h1000_0000: begin +`ifndef TIMING + $write("%c", mem_la_wdata); + $fflush(); +`endif end - WBSTART:begin - 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 + 32'h2000_0000: begin + if (mem_la_wdata[31:0] == 123456789) + exit = 1; end - WBEND: begin - mem_ready <= 1'b0; - - state <= IDLE; + default: begin + if (mem_la_wstrb[0]) memory[mem_la_addr + 0] <= mem_la_wdata[ 7: 0]; + if (mem_la_wstrb[1]) memory[mem_la_addr + 1] <= mem_la_wdata[15: 8]; + if (mem_la_wstrb[2]) memory[mem_la_addr + 2] <= mem_la_wdata[23:16]; + if (mem_la_wstrb[3]) memory[mem_la_addr + 3] <= mem_la_wdata[31:24]; end - default: - state <= IDLE; endcase end end diff --git a/testbench_wb.v b/testbench_wb.v index 4e1a8eb..80dce12 100644 --- a/testbench_wb.v +++ b/testbench_wb.v @@ -64,7 +64,7 @@ module picorv32_wrapper #( output trace_valid, output [35:0] trace_data ); - wire tests_passed; + wire exit; reg [31:0] irq = 0; wire mem_instr; @@ -86,26 +86,6 @@ module picorv32_wrapper #( wire [31:0] wb_s2m_dat; wire wb_s2m_ack; - wb_ram #( - .depth (128*1024), - .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_we_i(wb_m2s_we), - - .mem_instr(mem_instr), - .tests_passed(tests_passed) - ); - picorv32_wb #( `ifndef SYNTH_TEST `ifdef SP_TEST @@ -121,6 +101,7 @@ module picorv32_wrapper #( `endif ) uut ( .trap (trap), + .exit(exit), .irq (irq), .trace_valid (trace_valid), .trace_data (trace_data), @@ -128,22 +109,13 @@ module picorv32_wrapper #( .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) ); reg [1023:0] firmware_file; initial begin if (!$value$plusargs("firmware=%s", firmware_file)) firmware_file = "firmware/firmware.hex"; - $readmemh(firmware_file, ram.mem); + $readmemh(firmware_file, uut.memory); end integer cycle_counter; @@ -154,7 +126,7 @@ module picorv32_wrapper #( repeat (10) @(posedge wb_clk); `endif $display("TRAP after %1d clock cycles", cycle_counter); - if (tests_passed) begin + if (exit) begin $display("ALL TESTS PASSED."); $finish; end else begin @@ -166,128 +138,3 @@ module picorv32_wrapper #( end end endmodule - -/* ISC License - * - * Verilog on-chip RAM with Wishbone interface - * - * Copyright (C) 2014, 2016 Olof Kindgren - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -module wb_ram #( - parameter depth = 256, - parameter memfile = "", - parameter VERBOSE = 0 -) ( - input wb_clk_i, - input wb_rst_i, - - input [31:0] wb_adr_i, - input [31:0] wb_dat_i, - input [3:0] wb_sel_i, - input wb_we_i, - input wb_cyc_i, - input wb_stb_i, - - output reg wb_ack_o, - output reg [31:0] wb_dat_o, - - input mem_instr, - output reg tests_passed -); - - reg verbose; - initial verbose = $test$plusargs("verbose") || VERBOSE; - - initial tests_passed = 0; - - reg [31:0] adr_r; - wire valid = wb_cyc_i & wb_stb_i; - - always @(posedge wb_clk_i) begin - adr_r <= wb_adr_i; - // Ack generation - wb_ack_o <= valid & !wb_ack_o; - if (wb_rst_i) - begin - adr_r <= {32{1'b0}}; - wb_ack_o <= 1'b0; - end - end - - wire ram_we = wb_we_i & valid & wb_ack_o; - - wire [31:0] waddr = adr_r[31:2]; - wire [31:0] raddr = wb_adr_i[31: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 (ram_we) begin - if (verbose) - $display("WR: ADDR=%08x DATA=%08x STRB=%04b", - adr_r, wb_dat_i, we); - - if (adr_r[31:0] == 32'h1000_0000) - if (verbose) begin - if (32 <= wb_dat_i[7:0] && wb_dat_i[7:0] < 128) - $display("OUT: '%c'", wb_dat_i[7:0]); - else - $display("OUT: %3d", wb_dat_i[7:0]); - end else begin - $write("%c", wb_dat_i[7:0]); -`ifndef VERILATOR - $fflush(); -`endif - end - else - if (adr_r[31:0] == 32'h2000_0000) - if (wb_dat_i[31:0] == 123456789) - tests_passed = 1; - end - end - - always @(posedge wb_clk_i) begin - if (waddr2 < 128 * 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]; - - end - - if (valid & wb_ack_o & !ram_we) - if (verbose) - $display("RD: ADDR=%08x DATA=%08x%s", adr_r, mem[raddr2], mem_instr ? " INSN" : ""); - - wb_dat_o <= mem[raddr2]; - end - - initial begin - if (memfile != "") - $readmemh(memfile, mem); - end -endmodule