Downgrade IP to Verilog 2005 to work with Icraus and Yosys Signed-off-by: Matthew Ballance <matt.ballance@gmail.com>
diff --git a/dv/bringup/Makefile b/dv/bringup/Makefile index ad7dbab..edbc363 100644 --- a/dv/bringup/Makefile +++ b/dv/bringup/Makefile
@@ -30,8 +30,6 @@ export PYTHONPATH PATH := $(PACKAGES_DIR)/python/bin:$(PATH) export PATH -COCOTB_PREFIX := $(shell $(PACKAGES_DIR)/python/bin/cocotb-config --prefix) -VPI_LIBS += $(COCOTB_PREFIX)/cocotb/libs/libcocotbvpi_modelsim.so VLSIM_CLKSPEC += -clkspec clk=10ns @@ -47,6 +45,9 @@ clean :: echo "TODO" + for sim in $(BRINGUP_DIR)/../common/*.mk; do \ + $(MAKE) -f $$sim clean; \ + done include $(BRINGUP_DIR)/../common/$(SIM).mk
diff --git a/dv/bringup/bringup_tb.sv b/dv/bringup/bringup_tb.sv index d28b0ee..39e33f6 100644 --- a/dv/bringup/bringup_tb.sv +++ b/dv/bringup/bringup_tb.sv
@@ -1,6 +1,9 @@ /**************************************************************************** * bringup_tb.sv ****************************************************************************/ +`ifdef IVERILOG +`timescale 1ns/1ns +`endif `ifndef MPRJ_IO_PADS `define MPRJ_IO_PADS 38 @@ -14,13 +17,37 @@ `ifdef HAVE_HDL_CLOCKGEN reg clk_r = 0; - assign clk_r = #5ns ~clk_r; + initial begin + forever begin + #10; + clk_r <= ~clk_r; + end + end + assign clk = clk_r; `endif +`ifdef IVERILOG + // Icarus requires help with timeout + // and wave capture + reg[31:0] timeout; + initial begin + if ($test$plusargs("dumpvars")) begin + $dumpfile("simx.vcd"); + $dumpvars(0, bringup_tb); + end + if (!$value$plusargs("timeout=%d", timeout)) begin + timeout=1000; + end + $display("--> Wait for timeout"); + # timeout; + $display("<-- Wait for timeout"); + $finish(); + end +`endif wire clock = clk; reg[15:0] reset_cnt; - reg[15:0] reset_key /*verilator public*/; + reg[15:0] reset_key /*verilator public*/ = 0; always @(posedge clock) begin if (reset_key != 16'ha520) begin
diff --git a/dv/bringup/python/bringup_tests/__pycache__/mgmt_mem_access.cpython-36.pyc b/dv/bringup/python/bringup_tests/__pycache__/mgmt_mem_access.cpython-36.pyc index 3ed6cd8..ca45710 100644 --- a/dv/bringup/python/bringup_tests/__pycache__/mgmt_mem_access.cpython-36.pyc +++ b/dv/bringup/python/bringup_tests/__pycache__/mgmt_mem_access.cpython-36.pyc Binary files differ
diff --git a/dv/bringup/python/bringup_tests/la_utils.py b/dv/bringup/python/bringup_tests/la_utils.py index 90976e8..e3c63b3 100644 --- a/dv/bringup/python/bringup_tests/la_utils.py +++ b/dv/bringup/python/bringup_tests/la_utils.py
@@ -7,13 +7,14 @@ class LaUtils(object): CLOCK_IDX = 127 RESET_IDX = 126 + CORE_RESET_IDX = 125 def __init__(self, la_bfm): self.la_bfm = la_bfm async def set_dut_clock_control(self, en): # First, set reset high and clock low - await self.la_bfm.set_bits(LaUtils.RESET_IDX, 1, 1) + await self.la_bfm.set_bits(LaUtils.RESET_IDX, 0, 1) await self.la_bfm.set_bits(LaUtils.CLOCK_IDX, 0, 1) if en: @@ -25,10 +26,15 @@ await self.la_bfm.set_oen(LaUtils.RESET_IDX, 1, 1) await self.la_bfm.set_oen(LaUtils.CLOCK_IDX, 1, 1) + async def set_core_reset(self, en): + if en: + await self.la_bfm.set_bits(LaUtils.CORE_RESET_IDX, 0, 1) + else: + await self.la_bfm.set_bits(LaUtils.CORE_RESET_IDX, 1, 1) async def reset_cycle_dut(self, cycles=10): # Set reset high - await self.la_bfm.set_bits(LaUtils.RESET_IDX, 1, 1) + await self.la_bfm.set_bits(LaUtils.RESET_IDX, 0, 1) await self.la_bfm.propagate() # Clock @@ -36,7 +42,7 @@ await self.clock_dut() # Set reset low - await self.la_bfm.set_bits(LaUtils.RESET_IDX, 0, 1) + await self.la_bfm.set_bits(LaUtils.RESET_IDX, 1, 1) await self.clock_dut() pass @@ -46,5 +52,6 @@ await self.la_bfm.propagate() await self.la_bfm.set_bits(LaUtils.CLOCK_IDX, 0, 1) await self.la_bfm.propagate() + \ No newline at end of file
diff --git a/dv/bringup/python/bringup_tests/mgmt_mem_access.py b/dv/bringup/python/bringup_tests/mgmt_mem_access.py index fbf7a38..1937cc8 100644 --- a/dv/bringup/python/bringup_tests/mgmt_mem_access.py +++ b/dv/bringup/python/bringup_tests/mgmt_mem_access.py
@@ -8,6 +8,7 @@ from wishbone_bfms.wb_initiator_bfm import WbInitiatorBfm from logic_analyzer_bfms.la_initiator_bfm import LaInitiatorBfm from random import Random +from bringup_tests.la_utils import LaUtils @cocotb.test() @@ -16,10 +17,22 @@ Hold the payload DUT in reset via the logic analyzer Meanwhile, test that the management interface can access memory """ + print("--> pybfms.init()") await pybfms.init() + print("<-- pybfms.init()") u_wb : WbInitiatorBfm = pybfms.find_bfm(".*u_wb") u_la : LaInitiatorBfm = pybfms.find_bfm(".*u_la") + print("u_wb=" + str(u_wb)) + print("u_la=" + str(u_la)) + + # Bring the system out of reset + la_utils = LaUtils(u_la) + print("--> reset_cycle_dut") + await la_utils.reset_cycle_dut(100) + print("<-- reset_cycle_dut") + await la_utils.set_dut_clock_control(False) + # Test that we can write and read dut 'ROM' wr_data = [] r = Random(0) @@ -36,4 +49,13 @@ print("PASS: " + hex(0x80000000+4*i)) else: print("FAIL: " + hex(0x80000000+4*i) + " expect " + hex(wr_data[i]) + " receive " + hex(data)) - + + # Release the processor from reset + await la_utils.set_core_reset(True) + for i in range(10): + await u_la.propagate() + await la_utils.set_core_reset(False) + + for i in range(1000): + await u_la.propagate() + \ No newline at end of file
diff --git a/dv/common/icarus.mk b/dv/common/icarus.mk index f0fc7c5..d9b319c 100644 --- a/dv/common/icarus.mk +++ b/dv/common/icarus.mk
@@ -17,25 +17,42 @@ PACKAGES_DIR := $(abspath $(COMMON_DIR)/../../packages) VLSIM := $(PACKAGES_DIR)/python/bin/vlsim PYBFMS_VPI_LIB := $(shell $(PACKAGES_DIR)/python/bin/pybfms lib) +COCOTB_PREFIX := $(shell $(PACKAGES_DIR)/python/bin/cocotb-config --prefix) +TIMEOUT?=1ms + +DEFINES += IVERILOG HAVE_HDL_CLOCKGEN + +ifeq (ms,$(findstring ms,$(TIMEOUT))) + timeout=$(shell expr $(subst ms,,$(TIMEOUT)) '*' 1000000) +else + ifeq (us,$(findstring us,$(TIMEOUT))) + timeout=$(shell expr $(subst us,,$(TIMEOUT)) '*' 1000) + else + ifeq (ns,$(findstring ns,$(TIMEOUT))) + timeout=$(shell expr $(subst ns,,$(TIMEOUT)) '*' 1) + else + ifeq (s,$(findstring s,$(TIMEOUT))) + timeout=$(shell expr $(subst s,,$(TIMEOUT)) '*' 1000000000) + else + timeout=error: unknown $(TIMEOUT) + endif + endif + endif +endif + +SIMV_ARGS += +timeout=$(timeout) SIMV=simv.vvp ifneq (,$(DEBUG)) -VLSIM_OPTIONS += --trace-fst -SIMV_ARGS += +vlsim.trace -SIMV := simv.debug -else -SIMV := simv.ndebug +SIMV_ARGS += +dumpvars endif -# Enable VPI for Verilator -VLSIM_OPTIONS += --vpi -VLSIM_OPTIONS += --top-module $(TOP_MODULE) - IVERILOG_OPTIONS += $(foreach inc,$(INCDIRS),-I $(inc)) IVERILOG_OPTIONS += $(foreach def,$(DEFINES),-D $(def)) -VVP_ARGS += $(foreach vpi,$(VPI_LIBS),-m $(vpi)) +VVP_OPTIONS += $(foreach vpi,$(VPI_LIBS),-m $(vpi)) -VPI_LIBS += $(PYBFMS_DPI_LIB) +VPI_LIBS += $(PYBFMS_VPI_LIB) +VPI_LIBS += $(COCOTB_PREFIX)/cocotb/libs/libcocotbvpi_icarus.vpl build : $(SIMV) @@ -43,7 +60,7 @@ iverilog -o $@ $(IVERILOG_OPTIONS) $(SRCS) pybfms_gen.v run : $(SIMV) - vvp $(SIMV) $(VVP_ARGS) + vvp $(VVP_OPTIONS) $(SIMV) $(SIMV_ARGS) pybfms_gen.v : $(PACKAGES_DIR)/python/bin/pybfms generate \
diff --git a/dv/common/vlsim.mk b/dv/common/vlsim.mk index 184767b..20c6e77 100644 --- a/dv/common/vlsim.mk +++ b/dv/common/vlsim.mk
@@ -19,6 +19,7 @@ PACKAGES_DIR := $(abspath $(COMMON_DIR)/../../packages) VLSIM := $(PACKAGES_DIR)/python/bin/vlsim PYBFMS_DPI_LIB := $(shell $(PACKAGES_DIR)/python/bin/pybfms lib) +COCOTB_PREFIX := $(shell $(PACKAGES_DIR)/python/bin/cocotb-config --prefix) ifneq (,$(DEBUG)) VLSIM_OPTIONS += --trace-fst @@ -37,6 +38,7 @@ SIMV_ARGS += $(foreach vpi,$(VPI_LIBS),+vpi=$(vpi)) DPI_LIBS += $(PYBFMS_DPI_LIB) +VPI_LIBS += $(COCOTB_PREFIX)/cocotb/libs/libcocotbvpi_verilator.so build : $(SIMV)
diff --git a/verilog/rtl/fwpayload.v b/verilog/rtl/fwpayload.v index f585e22..da198ef 100644 --- a/verilog/rtl/fwpayload.v +++ b/verilog/rtl/fwpayload.v
@@ -57,29 +57,35 @@ localparam N_TARGETS = 1; localparam TGT_ID_SRAM = 0; - wire[31:0] IC_I_ADR[N_INITIATORS-1:0]; - wire[31:0] IC_I_DAT_W[N_INITIATORS-1:0]; - wire[31:0] IC_I_DAT_R[N_INITIATORS-1:0]; - wire IC_I_CYC[N_INITIATORS-1:0]; - wire IC_I_ERR[N_INITIATORS-1:0]; - wire[3:0] IC_I_SEL[N_INITIATORS-1:0]; - wire IC_I_STB[N_INITIATORS-1:0]; - wire IC_I_ACK[N_INITIATORS-1:0]; - wire IC_I_WE[N_INITIATORS-1:0]; + // TBD + localparam TGT_ID_SPI = 1; + localparam TGT_ID_UART = 2; + localparam TGT_ID_GPIO = 3; + wire[32*N_INITIATORS-1:0] IC_I_ADR; + wire[32*N_INITIATORS-1:0] IC_I_DAT_W; + wire[32*N_INITIATORS-1:0] IC_I_DAT_R; + wire[N_INITIATORS-1:0] IC_I_CYC; + wire[N_INITIATORS-1:0] IC_I_ERR; + wire[4*N_INITIATORS-1:0] IC_I_SEL; + wire[N_INITIATORS-1:0] IC_I_STB; + wire[N_INITIATORS-1:0] IC_I_ACK; + wire[N_INITIATORS-1:0] IC_I_WE; - wire[31:0] IC_T_ADR[N_TARGETS:0]; - wire[31:0] IC_T_DAT_W[N_TARGETS:0]; - wire[31:0] IC_T_DAT_R[N_TARGETS:0]; - wire IC_T_CYC[N_TARGETS:0]; - wire IC_T_ERR[N_TARGETS:0]; - wire[3:0] IC_T_SEL[N_TARGETS:0]; - wire IC_T_STB[N_TARGETS:0]; - wire IC_T_ACK[N_TARGETS:0]; - wire IC_T_WE[N_TARGETS:0]; - + wire[32*(N_TARGETS+1)-1:0] IC_T_ADR; + wire[32*(N_TARGETS+1)-1:0] IC_T_DAT_W; + wire[32*(N_TARGETS+1)-1:0] IC_T_DAT_R; + wire[N_TARGETS:0] IC_T_CYC; + wire[N_TARGETS:0] IC_T_ERR; + wire[4*(N_TARGETS+1)-1:0] IC_T_SEL; + wire[N_TARGETS:0] IC_T_STB; + wire[N_TARGETS:0] IC_T_ACK; + wire[N_TARGETS:0] IC_T_WE; + + // Interconnect has a default target that + // to which unmapped accesses are directed assign IC_T_ACK[N_TARGETS] = 1; assign IC_T_ERR[N_TARGETS] = 1; - assign IC_T_DAT_R[N_TARGETS] = 0; + assign IC_T_DAT_R[32*N_TARGETS+:32] = 0; // Interconnect wb_interconnect_NxN #( @@ -120,12 +126,12 @@ /**************************************************************** * Connect management interface to port 1 on the interconnect ****************************************************************/ - assign IC_I_ADR[INIT_ID_MGMT] = wbs_adr_i; - assign IC_I_DAT_W[INIT_ID_MGMT] = wbs_dat_i; - assign wbs_dat_o = IC_I_DAT_R[INIT_ID_MGMT]; + assign IC_I_ADR[32*INIT_ID_MGMT+:32] = wbs_adr_i; + assign IC_I_DAT_W[32*INIT_ID_MGMT+:32] = wbs_dat_i; + assign wbs_dat_o = IC_I_DAT_R[32*INIT_ID_MGMT+:32]; assign IC_I_CYC[INIT_ID_MGMT] = wbs_cyc_i; // assign IC_I_ERR[INIT_ID_MGMT] = //wbs_cyc_i; - assign IC_I_SEL[INIT_ID_MGMT] = wbs_sel_i; + assign IC_I_SEL[4*INIT_ID_MGMT+:4] = wbs_sel_i; assign IC_I_STB[INIT_ID_MGMT] = wbs_stb_i; assign wbs_ack_o = IC_I_ACK[INIT_ID_MGMT]; assign IC_I_WE[INIT_ID_MGMT] = wbs_we_i; @@ -133,42 +139,38 @@ // Clock/reset control // Allow the logic analyzer to take control of clock/reset // Default to using the caravel clock/reset -// assign clk = (~la_oen[127]) ? la_data_in[127]: wb_clk_i; -// assign rst = (~la_oen[126]) ? la_data_in[126]: wb_rst_i; - assign clk = wb_clk_i; - assign rst = wb_rst_i; - - wire[31:0] iaddr; - reg[31:0] idata; - wire ivalid; - wire iready; - wire[31:0] daddr; - wire[31:0] dwdata; - wire[31:0] dwstb; - wire dwrite; - reg[31:0] drdata; - wire dvalid; - wire dready; + assign clk = (~la_oen[127]) ? la_data_in[127]: wb_clk_i; + assign rst = (~la_oen[126]) ? ~la_data_in[126]: wb_rst_i; + assign core_rst = (~la_oen[125]) ? ~la_data_in[125]: wb_rst_i; +// assign clk = wb_clk_i; +// assign rst = wb_rst_i; localparam RAM_BITS = 8; localparam ROM_BITS = 8; - fwrisc_rv32i u_core ( + fwrisc_rv32i_wb u_core ( .clock(clk), - .reset(rst), - - .iaddr(iaddr), - .idata(idata), - .ivalid(ivalid), - .iready(iready), - - .dvalid(dvalid), - .daddr(daddr), - .dwdata(dwdata), - .dwstb(dwstb), - .dwrite(dwrite), - .drdata(drdata), - .dready(dready) + .reset(core_rst), + + .wbi_adr_o(IC_I_ADR[32*INIT_ID_CORE_I+:32]), + .wbi_dat_o(IC_I_DAT_W[32*INIT_ID_CORE_I+:32]), + .wbi_dat_i(IC_I_DAT_R[32*INIT_ID_CORE_I+:32]), + .wbi_cyc_o(IC_I_CYC[INIT_ID_CORE_I]), + .wbi_err_i(IC_I_ERR[INIT_ID_CORE_I]), + .wbi_sel_o(IC_I_SEL[4*INIT_ID_CORE_I+:4]), + .wbi_stb_o(IC_I_STB[INIT_ID_CORE_I]), + .wbi_ack_i(IC_I_ACK[INIT_ID_CORE_I]), + .wbi_we_o(IC_I_WE[INIT_ID_CORE_I]), + + .wbd_adr_o(IC_I_ADR[32*INIT_ID_CORE_D+:32]), + .wbd_dat_o(IC_I_DAT_W[32*INIT_ID_CORE_D+:32]), + .wbd_dat_i(IC_I_DAT_R[32*INIT_ID_CORE_D+:32]), + .wbd_cyc_o(IC_I_CYC[INIT_ID_CORE_D]), + .wbd_err_i(IC_I_ERR[INIT_ID_CORE_D]), + .wbd_sel_o(IC_I_SEL[4*INIT_ID_CORE_D+:4]), + .wbd_stb_o(IC_I_STB[INIT_ID_CORE_D]), + .wbd_ack_i(IC_I_ACK[INIT_ID_CORE_D]), + .wbd_we_o(IC_I_WE[INIT_ID_CORE_D]) ); @@ -192,7 +194,7 @@ assign la_data_out[REG_PROBE_OFF+31:REG_PROBE_OFF] = reg_probe; assign la_data_out[PC_PROBE_OFF+31:PC_PROBE_OFF] = pc_probe; - assign la_data_out[IVALID_OFF] = u_core.u_core.instr_complete; +// assign la_data_out[IVALID_OFF] = u_core.u_core.instr_complete; // 640 pixels // 16x16? @@ -212,75 +214,22 @@ // ROM: 'h8000_0000 // RAM: 'h8000_8000 // LED: 'hC000_0000 - reg[7:0] ram_0[(1 << RAM_BITS)-1:0]; // 16k ram - reg[7:0] ram_1[(1 << RAM_BITS)-1:0]; // 16k ram - reg[7:0] ram_2[(1 << RAM_BITS)-1:0]; // 16k ram - reg[7:0] ram_3[(1 << RAM_BITS)-1:0]; // 16k ram - reg[31:0] rom[(1 << ROM_BITS)-1:0]; // 16k rom -// reg[31:0] led; - reg[31:0] tx_r; - reg iready_r, dready_r; - assign iready = iready_r; - assign dready = dready_r; - // initial begin // $readmemh("rom.hex", rom); // end - reg[31:0] addr_d; - reg[31:0] addr_i; - reg[31:0] led; - - assign io_out[31:0] = led; - - always @(posedge clk) begin - addr_d <= daddr; - addr_i <= iaddr; - - if (dvalid && dready && dwrite) begin - if (daddr[31:28] == 4'h8 && - daddr[15:12] == 4'h8) begin - // $display("Write to RAM: 'h%08h", daddr[13:2]); - if (dwstb[0]) ram_0[daddr[RAM_BITS+1:2]] <= dwdata[7:0]; - if (dwstb[1]) ram_1[daddr[RAM_BITS+1:2]] <= dwdata[15:8]; - if (dwstb[2]) ram_2[daddr[RAM_BITS+1:2]] <= dwdata[23:16]; - if (dwstb[3]) ram_3[daddr[RAM_BITS+1:2]] <= dwdata[31:24]; - end else if (daddr[31:28] == 4'hc) begin - if (daddr[3:2] == 4'h0) begin - led <= dwdata; - end else if (daddr[3:2] == 4'h1) begin - tx_r <= dwdata; - end - end - end - end - - always @(posedge clk) begin - // Prefer data access - if (dvalid) begin - dready_r <= 1; - iready_r <= 0; - end else if (ivalid) begin - iready_r <= 1; - dready_r <= 0; - end else begin - iready_r <= 0; - dready_r <= 0; - end - end - /**************************************************************** * Simple WB to SRAM bridge ****************************************************************/ reg[1:0] wb_bridge_state = 0; - wire[31:0] sram_adr_i = IC_T_ADR[TGT_ID_SRAM]; - wire[31:0] sram_dat_w = IC_T_DAT_W[TGT_ID_SRAM]; + wire[31:0] sram_adr_i = IC_T_ADR[32*TGT_ID_SRAM+:32]; + wire[31:0] sram_dat_w = IC_T_DAT_W[32*TGT_ID_SRAM+:32]; wire[31:0] sram_dat_r; - assign IC_T_DAT_R[TGT_ID_SRAM] = sram_dat_r; + assign IC_T_DAT_R[32*TGT_ID_SRAM+:32] = sram_dat_r; wire sram_cyc_i = IC_T_CYC[TGT_ID_SRAM]; assign IC_T_ERR[TGT_ID_SRAM] = 0; - wire[3:0] sram_sel_i = IC_T_SEL[TGT_ID_SRAM]; + wire[3:0] sram_sel_i = IC_T_SEL[4*TGT_ID_SRAM+:4]; wire sram_stb_i = IC_T_STB[TGT_ID_SRAM]; wire sram_ack_o; assign IC_T_ACK[TGT_ID_SRAM] = sram_ack_o; @@ -319,58 +268,13 @@ .a_sel(sram_sel_i)); assign sram_ack_o = (wb_bridge_state == 3); - - wire [31:0] storage_mgmt_addr = wbs_adr_i; // [ADDRESS_WIDTH+(DATA_WIDTH/32):(DATA_WIDTH/32)+1]; - wire storage_mgmt_rd_en = (wbs_cyc_i & wbs_stb_i & !wbs_we_i); - wire storage_mgmt_wr_en = (wbs_cyc_i & wbs_stb_i & wbs_we_i); - wire [3:0] storage_mgmt_byte_en = wbs_sel_i; - wire [31:0] storage_mgmt_wr_dat = wbs_dat_i; - wire [31:0] storage_mgmt_rd_dat; - - assign wbs_dat_o = storage_mgmt_rd_dat; - - assign wbs_ack_o = (wb_bridge_state == 2); - - // TODO: allow to read 'ram' too - assign storage_mgmt_rd_dat = rom[wbs_adr_i[ROM_BITS+1:2]]; - - always @(posedge wb_clk_i) begin - if (storage_mgmt_wr_en) begin - rom[storage_mgmt_addr[13:2]] <= storage_mgmt_wr_dat; - end - end - - always @* begin - if (addr_d[31:28] == 4'h8 && addr_d[15:12] == 4'h8) begin - drdata = { - ram_3[addr_d[RAM_BITS+1:2]], - ram_2[addr_d[RAM_BITS+1:2]], - ram_1[addr_d[RAM_BITS+1:2]], - ram_0[addr_d[RAM_BITS+1:2]] - }; - end else begin - drdata = rom[addr_d[13:2]]; - end - - if (addr_i[31:28] == 4'h8 && addr_i[15:12] == 4'h8) begin - idata = { - ram_3[addr_i[RAM_BITS+1:2]], - ram_2[addr_i[RAM_BITS+1:2]], - ram_1[addr_i[RAM_BITS+1:2]], - ram_0[addr_i[RAM_BITS+1:2]] - }; - end else begin - idata = rom[addr_i[ROM_BITS+2:2]]; - end - end - // Some form of general I/O // - GPIO? // - // Some form of specific I/O - // - UART? - // - SPI? + // - UART + // - SPI endmodule
diff --git a/verilog/rtl/wb_interconnect_NxN.sv b/verilog/rtl/wb_interconnect_NxN.sv index b87cf56..f3b0ce3 100644 --- a/verilog/rtl/wb_interconnect_NxN.sv +++ b/verilog/rtl/wb_interconnect_NxN.sv
@@ -8,55 +8,58 @@ * TODO: Add module documentation */ module wb_interconnect_NxN #( - parameter int WB_ADDR_WIDTH=32, - parameter int unsigned WB_DATA_WIDTH=32, - parameter int unsigned N_INITIATORS=1, - parameter int unsigned N_TARGETS=1, - parameter bit [N_INITIATORS*WB_ADDR_WIDTH-1:0] I_ADR_MASK = { + parameter WB_ADDR_WIDTH=32, + parameter WB_DATA_WIDTH=32, + parameter N_INITIATORS=1, + parameter N_TARGETS=1, + parameter [N_INITIATORS*WB_ADDR_WIDTH-1:0] I_ADR_MASK = { {8'hFF, {24{1'b0}} } }, parameter [N_TARGETS*WB_ADDR_WIDTH-1:0] T_ADR = { { 32'h2800_0000 } } ) ( - input clk, - input rst, - input[WB_ADDR_WIDTH-1:0] ADR[N_INITIATORS-1:0], - input[WB_DATA_WIDTH-1:0] DAT_W[N_INITIATORS-1:0], - output[WB_DATA_WIDTH-1:0] DAT_R[N_INITIATORS-1:0], - input CYC[N_INITIATORS-1:0], - output ERR[N_INITIATORS-1:0], - input[(WB_DATA_WIDTH/8)-1:0] SEL[N_INITIATORS-1:0], - input STB[N_INITIATORS-1:0], - output ACK[N_INITIATORS-1:0], - input WE[N_INITIATORS-1:0], + input clk, + input rst, + input[WB_ADDR_WIDTH*N_INITIATORS-1:0] ADR, + input[WB_DATA_WIDTH*N_INITIATORS-1:0] DAT_W, + output[WB_DATA_WIDTH*N_INITIATORS-1:0] DAT_R, + input[N_INITIATORS-1:0] CYC, + output[N_INITIATORS-1:0] ERR, + input[(WB_DATA_WIDTH/8)*N_INITIATORS-1:0] SEL, + input[N_INITIATORS-1:0] STB, + output[N_INITIATORS-1:0] ACK, + input[N_INITIATORS-1:0] WE, - output[WB_ADDR_WIDTH-1:0] TADR[N_TARGETS:0], - output[WB_DATA_WIDTH-1:0] TDAT_W[N_TARGETS:0], - input[WB_DATA_WIDTH-1:0] TDAT_R[N_TARGETS:0], - output TCYC[N_TARGETS:0], - input TERR[N_TARGETS:0], - output[(WB_DATA_WIDTH/8)-1:0] TSEL[N_TARGETS:0], - output TSTB[N_TARGETS:0], - input TACK[N_TARGETS:0], - output TWE[N_TARGETS:0] + output[WB_ADDR_WIDTH*(N_TARGETS+1)-1:0] TADR, + output[WB_DATA_WIDTH*(N_TARGETS+1)-1:0] TDAT_W, + input[WB_DATA_WIDTH*(N_TARGETS+1)-1:0] TDAT_R, + output[N_TARGETS:0] TCYC, + input[N_TARGETS:0] TERR, + output[(WB_DATA_WIDTH/8)*(N_TARGETS+1)-1:0] TSEL, + output[N_TARGETS:0] TSTB, + input[N_TARGETS:0] TACK, + output[N_TARGETS:0] TWE ); - localparam int WB_DATA_MSB = (WB_DATA_WIDTH-1); - localparam int N_INIT_ID_BITS = (N_INITIATORS>1)?$clog2(N_INITIATORS):1; - localparam int N_TARG_ID_BITS = $clog2(N_TARGETS+1); - localparam bit[N_TARG_ID_BITS:0] NO_TARGET = {(N_TARG_ID_BITS+1){1'b1}}; - localparam bit[N_INIT_ID_BITS:0] NO_INITIATOR = {(N_INIT_ID_BITS+1){1'b1}}; + localparam WB_DATA_MSB = (WB_DATA_WIDTH-1); + localparam N_INIT_ID_BITS = (N_INITIATORS>1)?$clog2(N_INITIATORS):1; + localparam N_TARG_ID_BITS = $clog2(N_TARGETS+1); + localparam NO_TARGET = {(N_TARG_ID_BITS+1){1'b1}}; + localparam NO_INITIATOR = {(N_INIT_ID_BITS+1){1'b1}}; // Interface to the decode-fail target // wb_if TERR(); function reg[N_TARG_ID_BITS:0] addr2targ_id( - reg[N_INIT_ID_BITS-1:0] initiator, - reg[WB_ADDR_WIDTH-1:0] addr + input reg[N_INIT_ID_BITS-1:0] initiator, + input reg[WB_ADDR_WIDTH-1:0] addr ); + integer i; + begin + addr2targ_id = N_TARGETS; // $display("addr2targ_id: 'h%08h 'h%08h", addr, ADDR_RANGES); - for (int i=0; i<N_TARGETS; i+=1) begin + for (i=0; i<N_TARGETS; i+=1) begin // $display("Address Range: %0d 'h%08h..'h%08h", i, // ADDR_RANGES[(WB_ADDR_WIDTH*(i+2)-1)-:WB_ADDR_WIDTH], // ADDR_RANGES[(WB_ADDR_WIDTH*(i+1)-1)-:WB_ADDR_WIDTH]); @@ -65,16 +68,15 @@ (addr&I_ADR_MASK[(WB_ADDR_WIDTH*(i+1))-1-:WB_ADDR_WIDTH]) == (T_ADR[(WB_ADDR_WIDTH*(i+1))-1-:WB_ADDR_WIDTH])) begin $display("Address 'h%08h: range=%0d", addr, N_TARGETS-1); - return N_TARGETS-1; + addr2targ_id = N_TARGETS-1; end end - $display("%t: Address 'h%08h - decode fail", $time, addr); - return (N_TARGETS); + end endfunction // Read request state machine - // Master state machine + // Initiator state machine reg[2:0] initiator_state[N_INITIATORS-1:0]; reg[N_TARG_ID_BITS:0] initiator_selected_target[N_INITIATORS-1:0]; wire initiator_gnt[N_TARGETS:0]; @@ -83,7 +85,7 @@ generate genvar m_i; - for (m_i=0; m_i<N_INITIATORS; m_i++) begin : block_m_i + for (m_i=0; m_i<N_INITIATORS; m_i=m_i+1) begin : block_m_i always @(posedge clk) begin if (rst == 1) begin initiator_state[m_i] <= 0; @@ -95,7 +97,7 @@ initiator_state[m_i] <= 1; initiator_selected_target[m_i] <= addr2targ_id( m_i, - ADR[m_i] + ADR[WB_ADDR_WIDTH*m_i+:WB_ADDR_WIDTH] ); // $display("Master %0d => Slave %0d", m_i, addr2targ_id(m_i, ADR[m_i])); end @@ -118,8 +120,8 @@ generate genvar m_req_i, m_req_j; - for (m_req_i=0; m_req_i <(N_TARGETS+1); m_req_i++) begin : block_m_req_i - for (m_req_j=0; m_req_j < N_INITIATORS; m_req_j++) begin : block_m_req_j + for (m_req_i=0; m_req_i <(N_TARGETS+1); m_req_i=m_req_i+1) begin : block_m_req_i + for (m_req_j=0; m_req_j < N_INITIATORS; m_req_j=m_req_j+1) begin : block_m_req_j assign initiator_target_req[m_req_i][m_req_j] = (initiator_selected_target[m_req_j] == m_req_i); end end @@ -128,7 +130,7 @@ generate genvar s_arb_i; - for (s_arb_i=0; s_arb_i<(N_TARGETS+1); s_arb_i++) begin : s_arb + for (s_arb_i=0; s_arb_i<(N_TARGETS+1); s_arb_i=s_arb_i+1) begin : s_arb wb_NxN_arbiter #( .N_REQ (N_INITIATORS) ) @@ -147,7 +149,7 @@ generate genvar s_am_i; - for (s_am_i=0; s_am_i<(N_TARGETS+1); s_am_i++) begin : block_s_am_i + for (s_am_i=0; s_am_i<(N_TARGETS+1); s_am_i=s_am_i+1) begin : block_s_am_i assign target_active_initiator[s_am_i] = (initiator_gnt[s_am_i])?initiator_gnt_id[s_am_i]:NO_INITIATOR; end @@ -157,11 +159,12 @@ generate genvar s2m_i; - for (s2m_i=0; s2m_i<N_INITIATORS; s2m_i++) begin : block_s2m_i - assign DAT_R[s2m_i] = (initiator_selected_target[s2m_i] != NO_TARGET && - initiator_gnt[initiator_selected_target[s2m_i]] && - initiator_gnt_id[initiator_selected_target[s2m_i]] == s2m_i)? - TDAT_R[initiator_selected_target[s2m_i]]:0; + for (s2m_i=0; s2m_i<N_INITIATORS; s2m_i=s2m_i+1) begin : block_s2m_i + assign DAT_R[WB_DATA_WIDTH*s2m_i+:WB_DATA_WIDTH] = + (initiator_selected_target[s2m_i] != NO_TARGET && + initiator_gnt[initiator_selected_target[s2m_i]] && + initiator_gnt_id[initiator_selected_target[s2m_i]] == s2m_i)? + TDAT_R[WB_DATA_WIDTH*initiator_selected_target[s2m_i]+:WB_DATA_WIDTH]:0; assign ERR[s2m_i] = (initiator_selected_target[s2m_i] != NO_TARGET && initiator_gnt[initiator_selected_target[s2m_i]] && initiator_gnt_id[initiator_selected_target[s2m_i]] == s2m_i)? @@ -176,11 +179,15 @@ // WB signals to target mux generate genvar m2s_i; - for(m2s_i=0; m2s_i<(N_TARGETS+1); m2s_i++) begin : WB_M2S_assign - assign TADR[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:ADR[target_active_initiator[m2s_i]]; - assign TDAT_W[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:DAT_W[target_active_initiator[m2s_i]]; + for(m2s_i=0; m2s_i<(N_TARGETS+1); m2s_i=m2s_i+1) begin : WB_M2S_assign + assign TADR[WB_ADDR_WIDTH*m2s_i+:WB_ADDR_WIDTH] = + (target_active_initiator[m2s_i] == NO_INITIATOR)?0:ADR[WB_ADDR_WIDTH*target_active_initiator[m2s_i]+:WB_ADDR_WIDTH]; + assign TDAT_W[WB_DATA_WIDTH*m2s_i+:WB_DATA_WIDTH] = + (target_active_initiator[m2s_i] == NO_INITIATOR)?0:DAT_W[WB_DATA_WIDTH*target_active_initiator[m2s_i]+:WB_DATA_WIDTH]; assign TCYC[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:CYC[target_active_initiator[m2s_i]]; - assign TSEL[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:SEL[target_active_initiator[m2s_i]]; + assign TSEL[(WB_DATA_WIDTH/8)*m2s_i+:(WB_DATA_WIDTH/8)] = + (target_active_initiator[m2s_i] == NO_INITIATOR)?0: + SEL[(WB_DATA_WIDTH/8)*target_active_initiator[m2s_i]+:(WB_DATA_WIDTH/8)]; assign TSTB[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:STB[target_active_initiator[m2s_i]]; assign TWE[m2s_i] = (target_active_initiator[m2s_i] == NO_INITIATOR)?0:WE[target_active_initiator[m2s_i]]; end @@ -202,7 +209,7 @@ endmodule module wb_NxN_arbiter #( - parameter int N_REQ=2 + parameter N_REQ=2 ) ( input clk, input rst, @@ -233,7 +240,7 @@ generate genvar gnt_ppc_i; - for (gnt_ppc_i=N_REQ-1; gnt_ppc_i>=0; gnt_ppc_i--) begin : block_gnt_ppc_i + for (gnt_ppc_i=N_REQ-1; gnt_ppc_i>=0; gnt_ppc_i=gnt_ppc_i-1) begin : block_gnt_ppc_i if (gnt_ppc_i == 0) begin assign gnt_ppc[gnt_ppc_i] = last_gnt[0]; end else begin @@ -246,7 +253,7 @@ generate genvar unmasked_gnt_i; - for (unmasked_gnt_i=0; unmasked_gnt_i<N_REQ; unmasked_gnt_i++) begin : block_unmasked_gnt_i + for (unmasked_gnt_i=0; unmasked_gnt_i<N_REQ; unmasked_gnt_i=unmasked_gnt_i+1) begin : block_unmasked_gnt_i // Prioritized unmasked grant vector. Grant to the lowest active grant if (unmasked_gnt_i == 0) begin assign unmasked_gnt[unmasked_gnt_i] = req[unmasked_gnt_i]; @@ -260,7 +267,7 @@ generate genvar masked_gnt_i; - for (masked_gnt_i=0; masked_gnt_i<N_REQ; masked_gnt_i++) begin : block_masked_gnt_i + for (masked_gnt_i=0; masked_gnt_i<N_REQ; masked_gnt_i=masked_gnt_i+1) begin : block_masked_gnt_i if (masked_gnt_i == 0) begin assign masked_gnt[masked_gnt_i] = (gnt_ppc_next[masked_gnt_i] & req[masked_gnt_i]); end else begin @@ -303,19 +310,20 @@ end end - function reg[$clog2(N_REQ)-1:0] gnt2id(reg[N_REQ-1:0] gnt); - automatic int i; - reg[$clog2(N_REQ)-1:0] result; + function reg[$clog2(N_REQ)-1:0] gnt2id(input reg[N_REQ-1:0] gnt); + integer i; + begin +// reg[$clog2(N_REQ)-1:0] result; - result = 0; + gnt2id = 0; for (i=0; i<N_REQ; i++) begin if (gnt[i]) begin - result |= i; + gnt2id |= i; end end - return result; + end endfunction endmodule