Connected storage area to mgmt_core - Added wishbone bridge in mgmt_soc to contain all logic needed for the core to interface with the storage area - Updated defs.h with the base addresses for the storage blocks - Added R/W test for the mgmt blocks
diff --git a/verilog/dv/caravel/defs.h b/verilog/dv/caravel/defs.h index c9c0714..0aba014 100644 --- a/verilog/dv/caravel/defs.h +++ b/verilog/dv/caravel/defs.h
@@ -12,8 +12,13 @@ extern uint32_t flashio_worker_begin; extern uint32_t flashio_worker_end; -// SYNTH_MEM (0x0100_0000) -#define reg_synth_mem (*(volatile uint32_t*)0x01000000) +// Storage area (MGMT: 0x0100_0000, User: 0x0200_0000) +#define reg_mgmt_block0 (*(volatile uint32_t*)0x01000000) +#define reg_mgmt_block1 (*(volatile uint32_t*)0x01100000) +#define reg_user_block0 (*(volatile uint32_t*)0x02000000) +#define reg_user_block1 (*(volatile uint32_t*)0x02100000) +#define reg_user_block2 (*(volatile uint32_t*)0x02200000) +#define reg_user_block3 (*(volatile uint32_t*)0x02300000) // UART (0x2000_0000) #define reg_uart_clkdiv (*(volatile uint32_t*)0x20000000)
diff --git a/verilog/dv/caravel/mgmt_soc/storage/Makefile b/verilog/dv/caravel/mgmt_soc/storage/Makefile new file mode 100644 index 0000000..c7ee607 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/Makefile
@@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +BEHAVIOURAL_MODELS = ../../ + +GCC_PATH?=/ef/apps/bin +PDK_PATH?=/ef/tech/SW/sky130A + +.SUFFIXES: + +PATTERN = storage + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(PDK_PATH) -I $(BEHAVIOURAL_MODELS) \ + -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + ${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all +
diff --git a/verilog/dv/caravel/mgmt_soc/storage/storage.c b/verilog/dv/caravel/mgmt_soc/storage/storage.c new file mode 100644 index 0000000..62a9428 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/storage.c
@@ -0,0 +1,70 @@ +#include "../../defs.h" + +// -------------------------------------------------------- + +/* + Storage area Test + It uses GPIO to flag the success or failure of the test +*/ + +void main() +{ + int i; + volatile uint32_t* ram_addr; + /* Upper 16 user area pins are configured to be GPIO output */ + + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + + // Apply configuration + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // start test + reg_mprj_datal = 0xA0400000; + + // Test Management R/W block0 + for (i=0; i<10; i++){ + ram_addr = ®_mgmt_block0 + i; + *ram_addr = i*5000 + 10000; + } + + for (i=0; i<10; i++){ + ram_addr = ®_mgmt_block0 + i; + if ((i*5000+10000) != *ram_addr) + reg_mprj_datal = 0xAB400000; + } + + reg_mprj_datal = 0xAB410000; + + // Test Management R/W block1 + reg_mprj_datal = 0xA0200000; + for (i=0; i<10; i++){ + ram_addr = ®_mgmt_block1 + i; + *ram_addr = i*5000 + 10000; + } + + for (i=0; i<10; i++){ + ram_addr = ®_mgmt_block1 + i; + if ((i*5000+10000) != *ram_addr) + reg_mprj_datal = 0xAB200000; + } + + reg_mprj_datal = 0xAB210000; +} +
diff --git a/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v b/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v new file mode 100644 index 0000000..e664641 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v
@@ -0,0 +1,154 @@ +/* + * StriVe - A full example SoC using PicoRV32 in SkyWater s8 + * + * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at> + * Copyright (C) 2018 Tim Edwards <tim@efabless.com> + * + * 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. + * + */ + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module storage_tb; + reg clock; + reg RSTB; + reg power1, power2; + + wire gpio; + wire [15:0] checkbits; + wire [37:0] mprj_io; + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + assign checkbits = mprj_io[31:16]; + + // External clock is used by default. Make this artificially fast for the + // simulation. Normally this would be a slow clock and the digital PLL + // would be the fast clock. + + always #10 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("storage.vcd"); + $dumpvars(0, storage_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (100) begin + repeat (1000) @(posedge clock); + //$display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Storage (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + RSTB <= 1'b0; + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + always @(checkbits) begin + if(checkbits == 16'hA040) begin + $display("Mem Test storage MGMT block0 (RTL) [word rw] started"); + end + else if(checkbits == 16'hAB40) begin + $display("%c[1;31m",27); + $display("Monitor: Test storage MGMT block0 (RTL) [word rw] failed"); + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB41) begin + $display("Monitor: Test storage MGMT block0 (RTL) [word rw] passed"); + end + else if(checkbits == 16'hA020) begin + $display("Mem Test storage MGMT block1 (RTL) [word rw] started"); + end + else if(checkbits == 16'hAB20) begin + $display("%c[1;31m",27); + $display("Monitor: Test storage MGMT block1 (RTL) [word rw] failed"); + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB21) begin + $display("Monitor: Test storage MGMT block1 (RTL) [word rw] passed"); + $finish; + end + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VSS = 1'b0; + assign VDD3V3 = power1; + assign VDD1V8 = power2; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("storage.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule
diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v index 4aba1fe..d7c123f 100644 --- a/verilog/rtl/caravel.v +++ b/verilog/rtl/caravel.v
@@ -41,15 +41,18 @@ `include "gpio_control_block.v" `include "clock_div.v" `include "simple_por.v" +`include "storage_bridge_wb.v" +`include "sram_1rw1r_32_256_8_sky130.v" +`include "storage.v" /*------------------------------*/ /* Include user project here */ /*------------------------------*/ `include "user_proj_example.v" -`ifdef USE_OPENRAM - `include "sram_1rw1r_32_256_8_sky130.v" -`endif +// `ifdef USE_OPENRAM +// `include "sram_1rw1r_32_256_8_sky130.v" +// `endif module caravel ( inout vddio, // Common 3.3V padframe/ESD power @@ -313,6 +316,30 @@ wire mprj_vdd_pwrgood; wire mprj2_vdd_pwrgood; + // Storage area + // Management R/W interface + wire [`MGMT_BLOCKS-1:0] mgmt_ena; + wire [`MGMT_BLOCKS-1:0] mgmt_wen; + wire [(`MGMT_BLOCKS*4)-1:0] mgmt_wen_mask; + wire [7:0] mgmt_addr; + wire [31:0] mgmt_wdata; + wire [(`MGMT_BLOCKS*32)-1:0] mgmt_rdata; + // Management RO interface + wire [`USER_BLOCKS-1:0] mgmt_user_ena; + wire [7:0] mgmt_user_addr; + wire [(`USER_BLOCKS*32)-1:0] mgmt_user_rdata; + // User R/W interface + wire [`USER_BLOCKS-1:0] user_ena; + wire [`USER_BLOCKS-1:0] user_wen; + wire [(`USER_BLOCKS*4)-1:0] user_wen_mask; + wire [7:0] user_addr; + wire [31:0] user_wdata; + wire [(`USER_BLOCKS*32)-1:0] user_rdata; + // User RO interface + wire [`MGMT_BLOCKS-1:0] user_mgmt_ena; + wire [7:0] user_mgmt_addr; + wire [(`MGMT_BLOCKS*32)-1:0] user_mgmt_rdata; + mgmt_core soc ( `ifdef LVS .vdd(vccd), @@ -377,7 +404,18 @@ .mprj_ack_i(mprj_ack_i_core), .mprj_dat_i(mprj_dat_i_core), // mask data - .mask_rev(mask_rev) + .mask_rev(mask_rev), + // MGMT area R/W interface for mgmt RAM + .mgmt_ena(mgmt_ena), + .mgmt_wen_mask(mgmt_wen_mask), + .mgmt_wen(mgmt_wen), + .mgmt_addr(mgmt_addr), + .mgmt_wdata(mgmt_wdata), + .mgmt_rdata(mgmt_rdata), + // MGMT area RO interface for user RAM + .user_ena(mgmt_user_ena), + .user_addr(mgmt_user_addr), + .user_rdata(mgmt_user_rdata) ); /* Clock and reset to user space are passed through a tristate */ @@ -600,4 +638,35 @@ .X(rstb_l) ); + // Storage area + storage #( + .MGMT_BLOCKS(`MGMT_BLOCKS), + .USER_BLOCKS(`USER_BLOCKS) + ) storage( + .mgmt_clk(caravel_clk), + .mgmt_ena(mgmt_ena), + .mgmt_wen(mgmt_wen), + .mgmt_wen_mask(mgmt_wen_mask), + .mgmt_addr(mgmt_addr), + .mgmt_wdata(mgmt_wdata), + .mgmt_rdata(mgmt_rdata), + // Management RO interface + .mgmt_user_ena(mgmt_user_ena), + .mgmt_user_addr(mgmt_user_addr), + .mgmt_user_rdata(mgmt_user_rdata), + + // User R/W interface + .user_clk(caravel_clk2), + .user_ena(user_ena), + .user_wen(user_wen), + .user_wen_mask(user_wen_mask), + .user_addr(user_addr), + .user_wdata(user_wdata), + .user_rdata(user_rdata), + // User RO interface + .user_mgmt_ena(user_mgmt_ena), + .user_mgmt_addr(user_mgmt_addr), + .user_mgmt_rdata(user_mgmt_rdata) + ); + endmodule
diff --git a/verilog/rtl/defines.v b/verilog/rtl/defines.v index e2f457a..f9356c0 100644 --- a/verilog/rtl/defines.v +++ b/verilog/rtl/defines.v
@@ -8,3 +8,7 @@ // Type and size of soc_mem // `define USE_OPENRAM `define MEM_WORDS 256 + +// Number of RAM blocks for the mgmt_core +`define MGMT_BLOCKS 2 +`define USER_BLOCKS 4 \ No newline at end of file
diff --git a/verilog/rtl/mgmt_core.v b/verilog/rtl/mgmt_core.v index 863bd98..3e42f3e 100644 --- a/verilog/rtl/mgmt_core.v +++ b/verilog/rtl/mgmt_core.v
@@ -65,7 +65,20 @@ output core_rstn, // Metal programmed user ID / mask revision vector - input [31:0] mask_rev + input [31:0] mask_rev, + + // MGMT area R/W interface for mgmt RAM + output [`MGMT_BLOCKS-1:0] mgmt_ena, + output [(`MGMT_BLOCKS*4)-1:0] mgmt_wen_mask, + output [`MGMT_BLOCKS-1:0] mgmt_wen, + output [7:0] mgmt_addr, + output [31:0] mgmt_wdata, + input [(`MGMT_BLOCKS*32)-1:0] mgmt_rdata, + + // MGMT area RO interface for user RAM + output [`USER_BLOCKS-1:0] user_ena, + output [7:0] user_addr, + input [(`USER_BLOCKS*32)-1:0] user_rdata ); wire ext_clk_sel; wire pll_clk, pll_clk90; @@ -212,7 +225,18 @@ .mprj_adr_o(mprj_adr_o), .mprj_dat_o(mprj_dat_o), .mprj_ack_i(mprj_ack_i), - .mprj_dat_i(mprj_dat_i) + .mprj_dat_i(mprj_dat_i), + // MGMT area R/W interface for mgmt RAM + .mgmt_ena(mgmt_ena), + .mgmt_wen_mask(mgmt_wen_mask), + .mgmt_wen(mgmt_wen), + .mgmt_addr(mgmt_addr), + .mgmt_wdata(mgmt_wdata), + .mgmt_rdata(mgmt_rdata), + // MGMT area RO interface for user RAM + .user_ena(user_ena), + .user_addr(user_addr), + .user_rdata(user_rdata) ); digital_pll pll (
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v index 1139f1d..0183909 100644 --- a/verilog/rtl/mgmt_soc.v +++ b/verilog/rtl/mgmt_soc.v
@@ -137,7 +137,20 @@ output mprj_we_o, output [3:0] mprj_sel_o, output [31:0] mprj_adr_o, - output [31:0] mprj_dat_o + output [31:0] mprj_dat_o, + + // MGMT area R/W interface for mgmt RAM + output [`MGMT_BLOCKS-1:0] mgmt_ena, + output [(`MGMT_BLOCKS*4)-1:0] mgmt_wen_mask, + output [`MGMT_BLOCKS-1:0] mgmt_wen, + output [7:0] mgmt_addr, + output [31:0] mgmt_wdata, + input [(`MGMT_BLOCKS*32)-1:0] mgmt_rdata, + + // MGMT area RO interface for user RAM + output [`USER_BLOCKS-1:0] user_ena, + output [7:0] user_addr, + input [(`USER_BLOCKS*32)-1:0] user_rdata ); /* Memory reverted back to 256 words while memory has to be synthesized */ parameter [31:0] STACKADDR = (4*(`MEM_WORDS)); // end of memory @@ -146,6 +159,8 @@ // Slaves Base Addresses parameter RAM_BASE_ADR = 32'h 0000_0000; + parameter EXT_MRAM_BASE_ADR = 32'h 0100_0000; + parameter EXT_URAM_BASE_ADR = 32'h 0200_0000; parameter FLASH_BASE_ADR = 32'h 1000_0000; parameter UART_BASE_ADR = 32'h 2000_0000; parameter GPIO_BASE_ADR = 32'h 2100_0000; @@ -157,7 +172,7 @@ parameter FLASH_CTRL_CFG = 32'h 2D00_0000; parameter SYS_BASE_ADR = 32'h 2F00_0000; parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A - + // UART parameter UART_CLK_DIV = 8'h00; parameter UART_DATA = 8'h04; @@ -198,10 +213,23 @@ parameter TRAP_OUT = 8'h08; parameter IRQ_SRC = 8'h0c; + // Storage area RAM blocks + parameter [(`MGMT_BLOCKS*24)-1:0] MGMT_BLOCKS_ADR = { + {24'h 10_0000}, + {24'h 00_0000} + }; + + parameter [(`USER_BLOCKS*24)-1:0] USER_BLOCKS_ADR = { + {24'h 30_0000}, + {24'h 20_0000}, + {24'h 10_0000}, + {24'h 00_0000} + }; + // Wishbone Interconnect localparam ADR_WIDTH = 32; localparam DAT_WIDTH = 32; - localparam NUM_SLAVES = 12; + localparam NUM_SLAVES = 14; parameter [NUM_SLAVES*ADR_WIDTH-1: 0] ADR_MASK = { {8'hFF, {ADR_WIDTH-8{1'b0}}}, @@ -215,6 +243,8 @@ {8'hFF, {ADR_WIDTH-8{1'b0}}}, {8'hFF, {ADR_WIDTH-8{1'b0}}}, {8'hFF, {ADR_WIDTH-8{1'b0}}}, + {8'hFF, {ADR_WIDTH-8{1'b0}}}, + {8'hFF, {ADR_WIDTH-8{1'b0}}}, {8'hFF, {ADR_WIDTH-8{1'b0}}} }; @@ -230,6 +260,8 @@ {GPIO_BASE_ADR}, {UART_BASE_ADR}, {FLASH_BASE_ADR}, + {EXT_URAM_BASE_ADR}, + {EXT_MRAM_BASE_ADR}, {RAM_BASE_ADR} }; @@ -713,6 +745,51 @@ .wb_dat_o(mem_dat_o) ); + wire uram_stb_i; + wire mram_stb_i; + wire uram_ack_o; + wire mram_ack_o; + wire [31:0] mram_dat_o; + wire [31:0] uram_dat_o; + + // Storage area wishbone brige + storage_bridge_wb #( + .USER_BLOCKS(`USER_BLOCKS), + .MGMT_BLOCKS(`MGMT_BLOCKS), + .MGMT_BASE_ADR(EXT_MRAM_BASE_ADR), + .USER_BASE_ADR(EXT_URAM_BASE_ADR), + .MGMT_BLOCKS_ADR(MGMT_BLOCKS_ADR), + .USER_BLOCKS_ADR(USER_BLOCKS_ADR) + ) wb_bridge ( + .wb_clk_i(wb_clk_i), + .wb_rst_i(wb_rst_i), + + .wb_adr_i(cpu_adr_o), + .wb_dat_i(cpu_dat_o), + .wb_sel_i(cpu_sel_o), + .wb_we_i(cpu_we_o), + .wb_cyc_i(cpu_cyc_o), + .wb_stb_i({uram_stb_i, mram_stb_i}), + .wb_ack_o({uram_ack_o, mram_ack_o}), + .wb_mgmt_dat_o(mram_dat_o), + + // MGMT_AREA RO WB Interface + .wb_user_dat_o(uram_dat_o), + + // MGMT Area native memory interface + .mgmt_ena(mgmt_ena), + .mgmt_wen_mask(mgmt_wen_mask), + .mgmt_wen(mgmt_wen), + .mgmt_addr(mgmt_addr), + .mgmt_wdata(mgmt_wdata), + .mgmt_rdata(mgmt_rdata), + + // MGMT_AREA RO interface + .mgmt_user_ena(user_ena), + .mgmt_user_addr(user_addr), + .mgmt_user_rdata(user_rdata) + ); + // Wishbone intercon logic wb_intercon #( .AW(ADR_WIDTH), @@ -732,17 +809,17 @@ mprj_stb_o, mprj_ctrl_stb_i, la_stb_i, spi_master_stb_i, counter_timer1_stb_i, counter_timer0_stb_i, gpio_stb_i, uart_stb_i, - spimemio_flash_stb_i, mem_stb_i }), + spimemio_flash_stb_i,uram_stb_i, mram_stb_i, mem_stb_i }), .wbs_dat_i({ sys_dat_o, spimemio_cfg_dat_o, mprj_dat_i, mprj_ctrl_dat_o, la_dat_o, spi_master_dat_o, counter_timer1_dat_o, counter_timer0_dat_o, gpio_dat_o, uart_dat_o, - spimemio_flash_dat_o, mem_dat_o }), + spimemio_flash_dat_o, uram_dat_o, mram_dat_o, mem_dat_o }), .wbs_ack_i({ sys_ack_o, spimemio_cfg_ack_o, mprj_ack_i, mprj_ctrl_ack_o, la_ack_o, spi_master_ack_o, counter_timer1_ack_o, counter_timer0_ack_o, gpio_ack_o, uart_ack_o, - spimemio_flash_ack_o, mem_ack_o }) + spimemio_flash_ack_o, uram_ack_o, mram_ack_o, mem_ack_o }) ); endmodule