mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
style: mv and format the name of modules
This commit is contained in:
13 files changed
+390
-439
No files matched your search
+4
-3
@@ -4,6 +4,7 @@ CFLAGS=
|
||||
|
||||
WAVE := NONE
|
||||
|
||||
RTL :=
|
||||
# +behv_wave
|
||||
retrosim: retrosoc_tb.vvp retrosoc_fw.hex retrosoc_fw.bin
|
||||
vvp -N $< +firmware=retrosoc_fw.hex +behv_$(WAVE)
|
||||
@@ -12,7 +13,7 @@ retrosim: retrosoc_tb.vvp retrosoc_fw.hex retrosoc_fw.bin
|
||||
retrosynsim: retrosoc_syn_tb.vvp retrosoc_fw.hex
|
||||
vvp -N $< +firmware=retrosoc_fw.hex +syn_$(WAVE)
|
||||
|
||||
retrosoc_tb.vvp: retrosoc_tb.v retrosoc.v spram_model.v spimemio.v simpleuart.v picosoc.v picorv32.v spiflash.v ../tech/tc_io.v ../tech/tc_clk.v ../tech/tc_sram.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/verilog/sg13g2_io.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_core_behavioral_bm_bist.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_1024x16_c2_bm_bist.v
|
||||
retrosoc_tb.vvp: retrosoc_tb.v retrosoc_asic.v ./ip/spram_model.v ./ip/spimemio.v ./ip/simpleuart.v retrosoc.v picorv32.v ./ip/spiflash.v ../tech/tc_io.v ../tech/tc_clk.v ../tech/tc_sram.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/verilog/sg13g2_io.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_core_behavioral_bm_bist.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_1024x16_c2_bm_bist.v
|
||||
iverilog -s retrosoc_tb -o $@ $^
|
||||
|
||||
retrosoc_syn_tb.vvp: retrosoc_tb.v ../syn/yosys/out/retrosoc_yosys.v spiflash.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_stdcell/verilog/sg13g2_stdcell.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/verilog/sg13g2_io.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_core_behavioral_bm_bist.v ../syn/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_sram/verilog/RM_IHPSG13_1P_1024x16_c2_bm_bist.v
|
||||
@@ -44,8 +45,8 @@ spiflash_tb.vvp: spiflash.v spiflash_tb.v
|
||||
iverilog -s testbench -o $@ $^
|
||||
|
||||
# ---- ASIC Synthesis Tests ----
|
||||
cmos.log: spimemio.v simpleuart.v picosoc.v ../picorv32.v
|
||||
yosys -l cmos.log -p 'synth -top picosoc; abc -g cmos2; opt -fast; stat' $^
|
||||
cmos.log: spimemio.v simpleuart.v retrosoc.v ../picorv32.v
|
||||
yosys -l cmos.log -p 'synth -top retrosoc; abc -g cmos2; opt -fast; stat' $^
|
||||
|
||||
# ---- Clean ----
|
||||
clean:
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef RETROSOC
|
||||
# define MEM_TOTAL 0x4000 /* 16 KB */
|
||||
# define MEM_TOTAL 0x10000 /* 64 KB */
|
||||
#else
|
||||
# error "Set -DRETROSOC when compiling firmware.c"
|
||||
#endif
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,54 @@
|
||||
// 16x4KB=64KB
|
||||
module spram_model (
|
||||
input clk,
|
||||
input [ 3:0] wen,
|
||||
input [21:0] addr,
|
||||
input [31:0] wdata,
|
||||
output [31:0] rdata
|
||||
);
|
||||
|
||||
wire s_cs [15:0];
|
||||
wire [31:0] s_rdata[0:15];
|
||||
|
||||
assign s_cs[0] = ~addr[13] && ~addr[12] & ~addr[11] && ~addr[10];
|
||||
assign s_cs[1] = ~addr[13] && ~addr[12] & ~addr[11] && addr[10];
|
||||
assign s_cs[2] = ~addr[13] && ~addr[12] & addr[11] && ~addr[10];
|
||||
assign s_cs[3] = ~addr[13] && ~addr[12] & addr[11] && addr[10];
|
||||
assign s_cs[4] = ~addr[13] && addr[12] & ~addr[11] && ~addr[10];
|
||||
assign s_cs[5] = ~addr[13] && addr[12] & ~addr[11] && addr[10];
|
||||
assign s_cs[6] = ~addr[13] && addr[12] & addr[11] && ~addr[10];
|
||||
assign s_cs[7] = ~addr[13] && addr[12] & addr[11] && addr[10];
|
||||
assign s_cs[8] = ~addr[13] && ~addr[12] & ~addr[11] && ~addr[10];
|
||||
assign s_cs[9] = ~addr[13] && ~addr[12] & ~addr[11] && addr[10];
|
||||
assign s_cs[10] = addr[13] && ~addr[12] & addr[11] && ~addr[10];
|
||||
assign s_cs[11] = addr[13] && ~addr[12] & addr[11] && addr[10];
|
||||
assign s_cs[12] = addr[13] && addr[12] & ~addr[11] && ~addr[10];
|
||||
assign s_cs[13] = addr[13] && addr[12] & ~addr[11] && addr[10];
|
||||
assign s_cs[14] = addr[13] && addr[12] & addr[11] && ~addr[10];
|
||||
assign s_cs[15] = addr[13] && addr[12] & addr[11] && addr[10];
|
||||
|
||||
assign rdata = ({32{s_cs[0]}} & s_rdata[0]) | ({32{s_cs[1]}} & s_rdata[1]) |
|
||||
({32{s_cs[2]}} & s_rdata[2]) | ({32{s_cs[3]}} & s_rdata[3]) |
|
||||
({32{s_cs[4]}} & s_rdata[4]) | ({32{s_cs[5]}} & s_rdata[5]) |
|
||||
({32{s_cs[6]}} & s_rdata[6]) | ({32{s_cs[7]}} & s_rdata[7]) |
|
||||
({32{s_cs[8]}} & s_rdata[8]) | ({32{s_cs[9]}} & s_rdata[9]) |
|
||||
({32{s_cs[10]}} & s_rdata[10]) | ({32{s_cs[11]}} & s_rdata[11]) |
|
||||
({32{s_cs[12]}} & s_rdata[12]) | ({32{s_cs[13]}} & s_rdata[13]) |
|
||||
({32{s_cs[14]}} & s_rdata[14]) | ({32{s_cs[15]}} & s_rdata[15]);
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 16; i = i + 1) begin : gen_sram_block
|
||||
tc_sram_1024x32 u_ram (
|
||||
.clk_i (clk),
|
||||
.cs_i (s_cs[i]),
|
||||
.addr_i(addr[9:0]),
|
||||
.data_i(wdata),
|
||||
.mask_i(wen),
|
||||
.wren_i(|wen),
|
||||
.data_o(s_rdata[i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
-220
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
`ifndef PICORV32_REGS
|
||||
`ifdef PICORV32_V
|
||||
// `error "picosoc.v must be read before picorv32.v!"
|
||||
`endif
|
||||
|
||||
`define PICORV32_REGS picosoc_regs
|
||||
`endif
|
||||
|
||||
`ifndef PICOSOC_MEM
|
||||
`define PICOSOC_MEM picosoc_mem
|
||||
`endif
|
||||
|
||||
// this macro can be used to check if the verilog files in your
|
||||
// design are read in the correct order.
|
||||
`define PICOSOC_V
|
||||
|
||||
module picosoc #(
|
||||
parameter integer MEM_WORDS = 256,
|
||||
parameter [ 0:0] BARREL_SHIFTER = 1,
|
||||
parameter [ 0:0] COMPRESSED_ISA = 1,
|
||||
parameter [ 0:0] ENABLE_MUL = 0,
|
||||
parameter [ 0:0] ENABLE_FAST_MUL = 1,
|
||||
parameter [ 0:0] ENABLE_DIV = 1,
|
||||
parameter [ 0:0] ENABLE_IRQ = 0,
|
||||
parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
|
||||
parameter [31:0] STACKADDR = (4 * MEM_WORDS), // end of memory
|
||||
parameter [31:0] PROGADDR_RESET = 32'h0010_0000, // 1 MB into flash
|
||||
parameter [31:0] PROGADDR_IRQ = 32'h0000_0000
|
||||
) (
|
||||
input clk_i,
|
||||
input rst_n_i,
|
||||
output iomem_valid_o,
|
||||
input iomem_ready_i,
|
||||
output [ 3:0] iomem_wstrb_o,
|
||||
output [31:0] iomem_addr_o,
|
||||
output [31:0] iomem_wdata_o,
|
||||
input [31:0] iomem_rdata_i,
|
||||
output uart_tx_o,
|
||||
input uart_rx_i,
|
||||
output flash_csb_o,
|
||||
output flash_clk_o,
|
||||
output flash_io0_oe_o,
|
||||
output flash_io1_oe_o,
|
||||
output flash_io2_oe_o,
|
||||
output flash_io3_oe_o,
|
||||
output flash_io0_do_o,
|
||||
output flash_io1_do_o,
|
||||
output flash_io2_do_o,
|
||||
output flash_io3_do_o,
|
||||
input flash_io0_di_i,
|
||||
input flash_io1_di_i,
|
||||
input flash_io2_di_i,
|
||||
input flash_io3_di_i
|
||||
);
|
||||
|
||||
wire s_mem_valid;
|
||||
wire s_mem_instr;
|
||||
wire s_mem_ready;
|
||||
wire [31:0] s_mem_addr;
|
||||
wire [31:0] s_mem_wdata;
|
||||
wire [ 3:0] s_mem_wstrb;
|
||||
wire [31:0] s_mem_rdata;
|
||||
wire s_spimem_ready;
|
||||
wire [31:0] s_spimem_rdata;
|
||||
reg s_ram_ready;
|
||||
wire [31:0] s_ram_rdata;
|
||||
|
||||
assign iomem_valid_o = s_mem_valid && (s_mem_addr[31:24] > 8'h01);
|
||||
assign iomem_wstrb_o = s_mem_wstrb;
|
||||
assign iomem_addr_o = s_mem_addr;
|
||||
assign iomem_wdata_o = s_mem_wdata;
|
||||
|
||||
wire s_spimemio_cfgreg_sel = s_mem_valid && (s_mem_addr == 32'h0200_0000);
|
||||
wire [31:0] s_spimemio_cfgreg_do;
|
||||
wire s_simpleuart_reg_div_sel = s_mem_valid && (s_mem_addr == 32'h0200_0004);
|
||||
wire [31:0] s_simpleuart_reg_div_do;
|
||||
wire s_simpleuart_reg_dat_sel = s_mem_valid && (s_mem_addr == 32'h0200_0008);
|
||||
wire [31:0] s_simpleuart_reg_dat_do;
|
||||
wire s_simpleuart_reg_dat_wait;
|
||||
|
||||
assign s_mem_ready = (iomem_valid_o && iomem_ready_i) || s_spimem_ready || s_ram_ready || s_spimemio_cfgreg_sel ||
|
||||
s_simpleuart_reg_div_sel || (s_simpleuart_reg_dat_sel && !s_simpleuart_reg_dat_wait);
|
||||
|
||||
assign s_mem_rdata = (iomem_valid_o && iomem_ready_i) ? iomem_rdata_i : s_spimem_ready ? s_spimem_rdata : s_ram_ready ? s_ram_rdata :
|
||||
s_spimemio_cfgreg_sel ? s_spimemio_cfgreg_do : s_simpleuart_reg_div_sel ? s_simpleuart_reg_div_do :
|
||||
s_simpleuart_reg_dat_sel ? s_simpleuart_reg_dat_do : 32'h 0000_0000;
|
||||
|
||||
picorv32 #(
|
||||
.BARREL_SHIFTER (BARREL_SHIFTER),
|
||||
.COMPRESSED_ISA (COMPRESSED_ISA),
|
||||
.ENABLE_MUL (ENABLE_MUL),
|
||||
.ENABLE_FAST_MUL (ENABLE_FAST_MUL),
|
||||
.ENABLE_DIV (ENABLE_DIV),
|
||||
.ENABLE_IRQ (1),
|
||||
.ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS),
|
||||
.STACKADDR (STACKADDR),
|
||||
.PROGADDR_RESET (PROGADDR_RESET),
|
||||
.PROGADDR_IRQ (PROGADDR_IRQ)
|
||||
) u_picorv32 (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.mem_valid(s_mem_valid),
|
||||
.mem_instr(s_mem_instr),
|
||||
.mem_ready(s_mem_ready),
|
||||
.mem_addr (s_mem_addr),
|
||||
.mem_wdata(s_mem_wdata),
|
||||
.mem_wstrb(s_mem_wstrb),
|
||||
.mem_rdata(s_mem_rdata),
|
||||
.irq (32'd0)
|
||||
);
|
||||
|
||||
spimemio u_spimemio (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.valid (s_mem_valid && s_mem_addr >= 4 * MEM_WORDS && s_mem_addr < 32'h0200_0000),
|
||||
.ready (s_spimem_ready),
|
||||
.addr (s_mem_addr[23:0]),
|
||||
.rdata (s_spimem_rdata),
|
||||
.flash_csb (flash_csb_o),
|
||||
.flash_clk (flash_clk_o),
|
||||
.flash_io0_oe(flash_io0_oe_o),
|
||||
.flash_io1_oe(flash_io1_oe_o),
|
||||
.flash_io2_oe(flash_io2_oe_o),
|
||||
.flash_io3_oe(flash_io3_oe_o),
|
||||
.flash_io0_do(flash_io0_do_o),
|
||||
.flash_io1_do(flash_io1_do_o),
|
||||
.flash_io2_do(flash_io2_do_o),
|
||||
.flash_io3_do(flash_io3_do_o),
|
||||
.flash_io0_di(flash_io0_di_i),
|
||||
.flash_io1_di(flash_io1_di_i),
|
||||
.flash_io2_di(flash_io2_di_i),
|
||||
.flash_io3_di(flash_io3_di_i),
|
||||
.cfgreg_we (s_spimemio_cfgreg_sel ? s_mem_wstrb : 4'b0000),
|
||||
.cfgreg_di (s_mem_wdata),
|
||||
.cfgreg_do (s_spimemio_cfgreg_do)
|
||||
);
|
||||
|
||||
simpleuart u_simpleuart (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.ser_tx (uart_tx_o),
|
||||
.ser_rx (uart_rx_i),
|
||||
.reg_div_we (s_simpleuart_reg_div_sel ? s_mem_wstrb : 4'b0000),
|
||||
.reg_div_di (s_mem_wdata),
|
||||
.reg_div_do (s_simpleuart_reg_div_do),
|
||||
.reg_dat_we (s_simpleuart_reg_dat_sel ? s_mem_wstrb[0] : 1'b0),
|
||||
.reg_dat_re (s_simpleuart_reg_dat_sel && !s_mem_wstrb),
|
||||
.reg_dat_di (s_mem_wdata),
|
||||
.reg_dat_do (s_simpleuart_reg_dat_do),
|
||||
.reg_dat_wait(s_simpleuart_reg_dat_wait)
|
||||
);
|
||||
|
||||
always @(posedge clk_i) s_ram_ready <= s_mem_valid && !s_mem_ready && s_mem_addr < 4 * MEM_WORDS;
|
||||
|
||||
`PICOSOC_MEM u_picosoc_mem (
|
||||
.clk (clk_i),
|
||||
.wen ((s_mem_valid && !s_mem_ready && s_mem_addr < 4 * MEM_WORDS) ? s_mem_wstrb : 4'b0),
|
||||
.addr (s_mem_addr[23:2]),
|
||||
.wdata(s_mem_wdata),
|
||||
.rdata(s_ram_rdata)
|
||||
);
|
||||
endmodule
|
||||
|
||||
// Implementation note:
|
||||
// Replace the following two modules with wrappers for your SRAM cells.
|
||||
|
||||
module picosoc_regs (
|
||||
input clk,
|
||||
input wen,
|
||||
input [ 5:0] waddr,
|
||||
input [ 5:0] raddr1,
|
||||
input [ 5:0] raddr2,
|
||||
input [31:0] wdata,
|
||||
output [31:0] rdata1,
|
||||
output [31:0] rdata2
|
||||
);
|
||||
reg [31:0] regs[0:31];
|
||||
|
||||
always @(posedge clk) if (wen) regs[waddr[4:0]] <= wdata;
|
||||
|
||||
assign rdata1 = regs[raddr1[4:0]];
|
||||
assign rdata2 = regs[raddr2[4:0]];
|
||||
endmodule
|
||||
|
||||
module picosoc_mem (
|
||||
input clk,
|
||||
input [ 3:0] wen,
|
||||
input [21:0] addr,
|
||||
input [31:0] wdata,
|
||||
output reg [31:0] rdata
|
||||
);
|
||||
reg [31:0] mem[0:256-1];
|
||||
always @(posedge clk) begin
|
||||
rdata <= mem[addr];
|
||||
if (wen[0]) mem[addr][7:0] <= wdata[7:0];
|
||||
if (wen[1]) mem[addr][15:8] <= wdata[15:8];
|
||||
if (wen[2]) mem[addr][23:16] <= wdata[23:16];
|
||||
if (wen[3]) mem[addr][31:24] <= wdata[31:24];
|
||||
end
|
||||
endmodule
|
||||
|
||||
+196
-101
@@ -17,116 +17,211 @@
|
||||
*
|
||||
*/
|
||||
|
||||
`ifdef PICOSOC_V
|
||||
// `error "retrosoc.v must be read before picosoc.v!"
|
||||
`ifndef PICORV32_REGS
|
||||
`ifdef PICORV32_V
|
||||
// `error "picosoc.v must be read before picorv32.v!"
|
||||
`endif
|
||||
|
||||
`define PICOSOC_MEM spram_model
|
||||
`define PICORV32_REGS picosoc_regs
|
||||
`endif
|
||||
|
||||
`ifndef PICOSOC_MEM
|
||||
`define PICOSOC_MEM picosoc_mem
|
||||
`endif
|
||||
|
||||
// this macro can be used to check if the verilog files in your
|
||||
// design are read in the correct order.
|
||||
`define PICOSOC_V
|
||||
|
||||
module retrosoc #(
|
||||
// We limit the amount of memory in simulation
|
||||
// in order to avoid reduce simulation time
|
||||
// required for intialization of RAM
|
||||
parameter integer MEM_WORDS = 256
|
||||
parameter integer MEM_WORDS = 256,
|
||||
parameter [ 0:0] BARREL_SHIFTER = 1,
|
||||
parameter [ 0:0] COMPRESSED_ISA = 1,
|
||||
parameter [ 0:0] ENABLE_MUL = 0,
|
||||
parameter [ 0:0] ENABLE_FAST_MUL = 1,
|
||||
parameter [ 0:0] ENABLE_DIV = 1,
|
||||
parameter [ 0:0] ENABLE_IRQ = 0,
|
||||
parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
|
||||
parameter [31:0] STACKADDR = (4 * MEM_WORDS), // end of memory
|
||||
parameter [31:0] PROGADDR_RESET = 32'h0010_0000, // 1 MB into flash
|
||||
parameter [31:0] PROGADDR_IRQ = 32'h0000_0000
|
||||
) (
|
||||
input clk_i,
|
||||
input rst_n_i,
|
||||
output uart_tx_o_pad,
|
||||
input uart_rx_i_pad,
|
||||
output flash_csb_o_pad,
|
||||
output flash_clk_o_pad,
|
||||
inout flash_io0_io_pad,
|
||||
inout flash_io1_io_pad,
|
||||
inout flash_io2_io_pad,
|
||||
inout flash_io3_io_pad,
|
||||
output led1_o_pad,
|
||||
output led2_o_pad,
|
||||
output led3_o_pad,
|
||||
output led4_o_pad,
|
||||
output led5_o_pad,
|
||||
output led6_o_pad,
|
||||
output led7_o_pad
|
||||
input clk_i,
|
||||
input rst_n_i,
|
||||
output iomem_valid_o,
|
||||
input iomem_ready_i,
|
||||
output [ 3:0] iomem_wstrb_o,
|
||||
output [31:0] iomem_addr_o,
|
||||
output [31:0] iomem_wdata_o,
|
||||
input [31:0] iomem_rdata_i,
|
||||
output uart_tx_o,
|
||||
input uart_rx_i,
|
||||
output flash_csb_o,
|
||||
output flash_clk_o,
|
||||
output flash_io0_oe_o,
|
||||
output flash_io1_oe_o,
|
||||
output flash_io2_oe_o,
|
||||
output flash_io3_oe_o,
|
||||
output flash_io0_do_o,
|
||||
output flash_io1_do_o,
|
||||
output flash_io2_do_o,
|
||||
output flash_io3_do_o,
|
||||
input flash_io0_di_i,
|
||||
input flash_io1_di_i,
|
||||
input flash_io2_di_i,
|
||||
input flash_io3_di_i
|
||||
);
|
||||
|
||||
wire s_flash_csb_o, s_flash_clk_o;
|
||||
wire s_uart_rx_i, s_uart_tx_o;
|
||||
wire s_flash_io0_oe, s_flash_io0_do, s_flash_io0_di;
|
||||
wire s_flash_io1_oe, s_flash_io1_do, s_flash_io1_di;
|
||||
wire s_flash_io2_oe, s_flash_io2_do, s_flash_io2_di;
|
||||
wire s_flash_io3_oe, s_flash_io3_do, s_flash_io3_di;
|
||||
wire s_iomem_valid;
|
||||
reg r_iomem_ready;
|
||||
wire [ 3:0] s_iomem_wstrb;
|
||||
wire [31:0] s_iomem_addr;
|
||||
wire [31:0] s_iomem_wdata;
|
||||
reg [31:0] r_iomem_rdata;
|
||||
wire [ 7:0] s_leds;
|
||||
reg [31:0] r_gpio;
|
||||
wire s_mem_valid;
|
||||
wire s_mem_instr;
|
||||
wire s_mem_ready;
|
||||
wire [31:0] s_mem_addr;
|
||||
wire [31:0] s_mem_wdata;
|
||||
wire [ 3:0] s_mem_wstrb;
|
||||
wire [31:0] s_mem_rdata;
|
||||
wire s_spimem_ready;
|
||||
wire [31:0] s_spimem_rdata;
|
||||
reg s_ram_ready;
|
||||
wire [31:0] s_ram_rdata;
|
||||
|
||||
// verilog_format: off
|
||||
tc_io_tri_pad u_uart_tx_o_pad (.pad(uart_tx_o_pad), .c2p(s_uart_tx_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_uart_rx_i_pad (.pad(uart_rx_i_pad), .c2p(), .c2p_en(1'b0), .p2c(s_uart_rx_i));
|
||||
tc_io_tri_pad u_flash_csb_o_pad (.pad(flash_csb_o_pad), .c2p(s_flash_csb_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_flash_clk_o_pad (.pad(flash_clk_o_pad), .c2p(s_flash_clk_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_flash_io0_io_pad(.pad(flash_io0_io_pad), .c2p(s_flash_io0_do), .c2p_en(s_flash_io0_oe), .p2c(s_flash_io0_di));
|
||||
tc_io_tri_pad u_flash_io1_io_pad(.pad(flash_io1_io_pad), .c2p(s_flash_io1_do), .c2p_en(s_flash_io1_oe), .p2c(s_flash_io1_di));
|
||||
tc_io_tri_pad u_flash_io2_io_pad(.pad(flash_io2_io_pad), .c2p(s_flash_io2_do), .c2p_en(s_flash_io2_oe), .p2c(s_flash_io2_di));
|
||||
tc_io_tri_pad u_led1_o_pad (.pad(led1_o_pad), .c2p(s_leds[1]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led2_o_pad (.pad(led2_o_pad), .c2p(s_leds[2]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led3_o_pad (.pad(led3_o_pad), .c2p(s_leds[3]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led4_o_pad (.pad(led4_o_pad), .c2p(s_leds[4]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led5_o_pad (.pad(led5_o_pad), .c2p(s_leds[5]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led6_o_pad (.pad(led6_o_pad), .c2p(s_leds[6]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led7_o_pad (.pad(led7_o_pad), .c2p(s_leds[7]), .c2p_en(1'b1), .p2c());
|
||||
// verilog_format: on
|
||||
assign s_leds = r_gpio;
|
||||
assign iomem_valid_o = s_mem_valid && (s_mem_addr[31:24] > 8'h01);
|
||||
assign iomem_wstrb_o = s_mem_wstrb;
|
||||
assign iomem_addr_o = s_mem_addr;
|
||||
assign iomem_wdata_o = s_mem_wdata;
|
||||
|
||||
always @(posedge clk_i) begin
|
||||
if (!rst_n_i) begin
|
||||
r_gpio <= 0;
|
||||
end else begin
|
||||
r_iomem_ready <= 0;
|
||||
if (s_iomem_valid && !r_iomem_ready && s_iomem_addr[31:24] == 8'h03) begin
|
||||
r_iomem_ready <= 1;
|
||||
r_iomem_rdata <= r_gpio;
|
||||
if (s_iomem_wstrb[0]) r_gpio[7:0] <= s_iomem_wdata[7:0];
|
||||
if (s_iomem_wstrb[1]) r_gpio[15:8] <= s_iomem_wdata[15:8];
|
||||
if (s_iomem_wstrb[2]) r_gpio[23:16] <= s_iomem_wdata[23:16];
|
||||
if (s_iomem_wstrb[3]) r_gpio[31:24] <= s_iomem_wdata[31:24];
|
||||
end
|
||||
end
|
||||
end
|
||||
wire s_spimemio_cfgreg_sel = s_mem_valid && (s_mem_addr == 32'h0200_0000);
|
||||
wire [31:0] s_spimemio_cfgreg_do;
|
||||
wire s_simpleuart_reg_div_sel = s_mem_valid && (s_mem_addr == 32'h0200_0004);
|
||||
wire [31:0] s_simpleuart_reg_div_do;
|
||||
wire s_simpleuart_reg_dat_sel = s_mem_valid && (s_mem_addr == 32'h0200_0008);
|
||||
wire [31:0] s_simpleuart_reg_dat_do;
|
||||
wire s_simpleuart_reg_dat_wait;
|
||||
|
||||
picosoc #(
|
||||
.MEM_WORDS (MEM_WORDS),
|
||||
.BARREL_SHIFTER (1),
|
||||
.COMPRESSED_ISA (1),
|
||||
.ENABLE_FAST_MUL(1),
|
||||
.ENABLE_DIV (1)
|
||||
) u_picosoc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.uart_tx_o (s_uart_tx_o),
|
||||
.uart_rx_i (s_uart_rx_i),
|
||||
.flash_csb_o (s_flash_csb_o),
|
||||
.flash_clk_o (s_flash_clk_o),
|
||||
.flash_io0_oe_o(s_flash_io0_oe),
|
||||
.flash_io1_oe_o(s_flash_io1_oe),
|
||||
.flash_io2_oe_o(s_flash_io2_oe),
|
||||
.flash_io3_oe_o(s_flash_io3_oe),
|
||||
.flash_io0_do_o(s_flash_io0_do),
|
||||
.flash_io1_do_o(s_flash_io1_do),
|
||||
.flash_io2_do_o(s_flash_io2_do),
|
||||
.flash_io3_do_o(s_flash_io3_do),
|
||||
.flash_io0_di_i(s_flash_io0_di),
|
||||
.flash_io1_di_i(s_flash_io1_di),
|
||||
.flash_io2_di_i(s_flash_io2_di),
|
||||
.flash_io3_di_i(s_flash_io3_di),
|
||||
.iomem_valid_o (s_iomem_valid),
|
||||
.iomem_ready_i (r_iomem_ready),
|
||||
.iomem_wstrb_o (s_iomem_wstrb),
|
||||
.iomem_addr_o (s_iomem_addr),
|
||||
.iomem_wdata_o (s_iomem_wdata),
|
||||
.iomem_rdata_i (r_iomem_rdata)
|
||||
assign s_mem_ready = (iomem_valid_o && iomem_ready_i) || s_spimem_ready || s_ram_ready || s_spimemio_cfgreg_sel ||
|
||||
s_simpleuart_reg_div_sel || (s_simpleuart_reg_dat_sel && !s_simpleuart_reg_dat_wait);
|
||||
|
||||
assign s_mem_rdata = (iomem_valid_o && iomem_ready_i) ? iomem_rdata_i : s_spimem_ready ? s_spimem_rdata : s_ram_ready ? s_ram_rdata :
|
||||
s_spimemio_cfgreg_sel ? s_spimemio_cfgreg_do : s_simpleuart_reg_div_sel ? s_simpleuart_reg_div_do :
|
||||
s_simpleuart_reg_dat_sel ? s_simpleuart_reg_dat_do : 32'h 0000_0000;
|
||||
|
||||
picorv32 #(
|
||||
.BARREL_SHIFTER (BARREL_SHIFTER),
|
||||
.COMPRESSED_ISA (COMPRESSED_ISA),
|
||||
.ENABLE_MUL (ENABLE_MUL),
|
||||
.ENABLE_FAST_MUL (ENABLE_FAST_MUL),
|
||||
.ENABLE_DIV (ENABLE_DIV),
|
||||
.ENABLE_IRQ (1),
|
||||
.ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS),
|
||||
.STACKADDR (STACKADDR),
|
||||
.PROGADDR_RESET (PROGADDR_RESET),
|
||||
.PROGADDR_IRQ (PROGADDR_IRQ)
|
||||
) u_picorv32 (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.mem_valid(s_mem_valid),
|
||||
.mem_instr(s_mem_instr),
|
||||
.mem_ready(s_mem_ready),
|
||||
.mem_addr (s_mem_addr),
|
||||
.mem_wdata(s_mem_wdata),
|
||||
.mem_wstrb(s_mem_wstrb),
|
||||
.mem_rdata(s_mem_rdata),
|
||||
.irq (32'd0)
|
||||
);
|
||||
|
||||
spimemio u_spimemio (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.valid (s_mem_valid && s_mem_addr >= 4 * MEM_WORDS && s_mem_addr < 32'h0200_0000),
|
||||
.ready (s_spimem_ready),
|
||||
.addr (s_mem_addr[23:0]),
|
||||
.rdata (s_spimem_rdata),
|
||||
.flash_csb (flash_csb_o),
|
||||
.flash_clk (flash_clk_o),
|
||||
.flash_io0_oe(flash_io0_oe_o),
|
||||
.flash_io1_oe(flash_io1_oe_o),
|
||||
.flash_io2_oe(flash_io2_oe_o),
|
||||
.flash_io3_oe(flash_io3_oe_o),
|
||||
.flash_io0_do(flash_io0_do_o),
|
||||
.flash_io1_do(flash_io1_do_o),
|
||||
.flash_io2_do(flash_io2_do_o),
|
||||
.flash_io3_do(flash_io3_do_o),
|
||||
.flash_io0_di(flash_io0_di_i),
|
||||
.flash_io1_di(flash_io1_di_i),
|
||||
.flash_io2_di(flash_io2_di_i),
|
||||
.flash_io3_di(flash_io3_di_i),
|
||||
.cfgreg_we (s_spimemio_cfgreg_sel ? s_mem_wstrb : 4'b0000),
|
||||
.cfgreg_di (s_mem_wdata),
|
||||
.cfgreg_do (s_spimemio_cfgreg_do)
|
||||
);
|
||||
|
||||
simpleuart u_simpleuart (
|
||||
.clk (clk_i),
|
||||
.resetn (rst_n_i),
|
||||
.ser_tx (uart_tx_o),
|
||||
.ser_rx (uart_rx_i),
|
||||
.reg_div_we (s_simpleuart_reg_div_sel ? s_mem_wstrb : 4'b0000),
|
||||
.reg_div_di (s_mem_wdata),
|
||||
.reg_div_do (s_simpleuart_reg_div_do),
|
||||
.reg_dat_we (s_simpleuart_reg_dat_sel ? s_mem_wstrb[0] : 1'b0),
|
||||
.reg_dat_re (s_simpleuart_reg_dat_sel && !s_mem_wstrb),
|
||||
.reg_dat_di (s_mem_wdata),
|
||||
.reg_dat_do (s_simpleuart_reg_dat_do),
|
||||
.reg_dat_wait(s_simpleuart_reg_dat_wait)
|
||||
);
|
||||
|
||||
always @(posedge clk_i) s_ram_ready <= s_mem_valid && !s_mem_ready && s_mem_addr < 4 * MEM_WORDS;
|
||||
|
||||
`PICOSOC_MEM u_picosoc_mem (
|
||||
.clk (clk_i),
|
||||
.wen ((s_mem_valid && !s_mem_ready && s_mem_addr < 4 * MEM_WORDS) ? s_mem_wstrb : 4'b0),
|
||||
.addr (s_mem_addr[23:2]),
|
||||
.wdata(s_mem_wdata),
|
||||
.rdata(s_ram_rdata)
|
||||
);
|
||||
endmodule
|
||||
|
||||
// Implementation note:
|
||||
// Replace the following two modules with wrappers for your SRAM cells.
|
||||
|
||||
module picosoc_regs (
|
||||
input clk,
|
||||
input wen,
|
||||
input [ 5:0] waddr,
|
||||
input [ 5:0] raddr1,
|
||||
input [ 5:0] raddr2,
|
||||
input [31:0] wdata,
|
||||
output [31:0] rdata1,
|
||||
output [31:0] rdata2
|
||||
);
|
||||
reg [31:0] regs[0:31];
|
||||
|
||||
always @(posedge clk) if (wen) regs[waddr[4:0]] <= wdata;
|
||||
|
||||
assign rdata1 = regs[raddr1[4:0]];
|
||||
assign rdata2 = regs[raddr2[4:0]];
|
||||
endmodule
|
||||
|
||||
module picosoc_mem (
|
||||
input clk,
|
||||
input [ 3:0] wen,
|
||||
input [21:0] addr,
|
||||
input [31:0] wdata,
|
||||
output reg [31:0] rdata
|
||||
);
|
||||
// reg [31:0] mem[0:256-1];
|
||||
// always @(posedge clk) begin
|
||||
// rdata <= mem[addr];
|
||||
// if (wen[0]) mem[addr][7:0] <= wdata[7:0];
|
||||
// if (wen[1]) mem[addr][15:8] <= wdata[15:8];
|
||||
// if (wen[2]) mem[addr][23:16] <= wdata[23:16];
|
||||
// if (wen[3]) mem[addr][31:24] <= wdata[31:24];
|
||||
// end
|
||||
spram_model u_spram_model (
|
||||
.clk (clk),
|
||||
.wen (wen),
|
||||
.addr (addr),
|
||||
.wdata(wdata),
|
||||
.rdata(rdata)
|
||||
);
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
`ifdef PICOSOC_V
|
||||
// `error "retrosoc_asic.v must be read before retrosoc.v!"
|
||||
`endif
|
||||
|
||||
`define PICOSOC_MEM spram_model
|
||||
|
||||
module retrosoc_asic #(
|
||||
// We limit the amount of memory in simulation
|
||||
// in order to avoid reduce simulation time
|
||||
// required for intialization of RAM
|
||||
parameter integer MEM_WORDS = 256
|
||||
) (
|
||||
input clk_i,
|
||||
input rst_n_i,
|
||||
output uart_tx_o_pad,
|
||||
input uart_rx_i_pad,
|
||||
output flash_csb_o_pad,
|
||||
output flash_clk_o_pad,
|
||||
inout flash_io0_io_pad,
|
||||
inout flash_io1_io_pad,
|
||||
inout flash_io2_io_pad,
|
||||
inout flash_io3_io_pad,
|
||||
output led1_o_pad,
|
||||
output led2_o_pad,
|
||||
output led3_o_pad,
|
||||
output led4_o_pad,
|
||||
output led5_o_pad,
|
||||
output led6_o_pad,
|
||||
output led7_o_pad
|
||||
);
|
||||
|
||||
wire s_flash_csb_o, s_flash_clk_o;
|
||||
wire s_uart_rx_i, s_uart_tx_o;
|
||||
wire s_flash_io0_oe, s_flash_io0_do, s_flash_io0_di;
|
||||
wire s_flash_io1_oe, s_flash_io1_do, s_flash_io1_di;
|
||||
wire s_flash_io2_oe, s_flash_io2_do, s_flash_io2_di;
|
||||
wire s_flash_io3_oe, s_flash_io3_do, s_flash_io3_di;
|
||||
wire s_iomem_valid;
|
||||
reg r_iomem_ready;
|
||||
wire [ 3:0] s_iomem_wstrb;
|
||||
wire [31:0] s_iomem_addr;
|
||||
wire [31:0] s_iomem_wdata;
|
||||
reg [31:0] r_iomem_rdata;
|
||||
wire [ 7:0] s_leds;
|
||||
reg [31:0] r_gpio;
|
||||
|
||||
// verilog_format: off
|
||||
tc_io_tri_pad u_uart_tx_o_pad (.pad(uart_tx_o_pad), .c2p(s_uart_tx_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_uart_rx_i_pad (.pad(uart_rx_i_pad), .c2p(), .c2p_en(1'b0), .p2c(s_uart_rx_i));
|
||||
tc_io_tri_pad u_flash_csb_o_pad (.pad(flash_csb_o_pad), .c2p(s_flash_csb_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_flash_clk_o_pad (.pad(flash_clk_o_pad), .c2p(s_flash_clk_o), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_flash_io0_io_pad(.pad(flash_io0_io_pad), .c2p(s_flash_io0_do), .c2p_en(s_flash_io0_oe), .p2c(s_flash_io0_di));
|
||||
tc_io_tri_pad u_flash_io1_io_pad(.pad(flash_io1_io_pad), .c2p(s_flash_io1_do), .c2p_en(s_flash_io1_oe), .p2c(s_flash_io1_di));
|
||||
tc_io_tri_pad u_flash_io2_io_pad(.pad(flash_io2_io_pad), .c2p(s_flash_io2_do), .c2p_en(s_flash_io2_oe), .p2c(s_flash_io2_di));
|
||||
tc_io_tri_pad u_flash_io3_io_pad(.pad(flash_io3_io_pad), .c2p(s_flash_io3_do), .c2p_en(s_flash_io3_oe), .p2c(s_flash_io3_di));
|
||||
tc_io_tri_pad u_led1_o_pad (.pad(led1_o_pad), .c2p(s_leds[1]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led2_o_pad (.pad(led2_o_pad), .c2p(s_leds[2]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led3_o_pad (.pad(led3_o_pad), .c2p(s_leds[3]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led4_o_pad (.pad(led4_o_pad), .c2p(s_leds[4]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led5_o_pad (.pad(led5_o_pad), .c2p(s_leds[5]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led6_o_pad (.pad(led6_o_pad), .c2p(s_leds[6]), .c2p_en(1'b1), .p2c());
|
||||
tc_io_tri_pad u_led7_o_pad (.pad(led7_o_pad), .c2p(s_leds[7]), .c2p_en(1'b1), .p2c());
|
||||
// verilog_format: on
|
||||
assign s_leds = r_gpio;
|
||||
|
||||
always @(posedge clk_i) begin
|
||||
if (!rst_n_i) begin
|
||||
r_gpio <= 0;
|
||||
end else begin
|
||||
r_iomem_ready <= 0;
|
||||
if (s_iomem_valid && !r_iomem_ready && s_iomem_addr[31:24] == 8'h03) begin
|
||||
r_iomem_ready <= 1;
|
||||
r_iomem_rdata <= r_gpio;
|
||||
if (s_iomem_wstrb[0]) r_gpio[7:0] <= s_iomem_wdata[7:0];
|
||||
if (s_iomem_wstrb[1]) r_gpio[15:8] <= s_iomem_wdata[15:8];
|
||||
if (s_iomem_wstrb[2]) r_gpio[23:16] <= s_iomem_wdata[23:16];
|
||||
if (s_iomem_wstrb[3]) r_gpio[31:24] <= s_iomem_wdata[31:24];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
retrosoc #(
|
||||
.MEM_WORDS (MEM_WORDS),
|
||||
.BARREL_SHIFTER (1),
|
||||
.COMPRESSED_ISA (1),
|
||||
.ENABLE_FAST_MUL(1),
|
||||
.ENABLE_DIV (1)
|
||||
) u_retrosoc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.uart_tx_o (s_uart_tx_o),
|
||||
.uart_rx_i (s_uart_rx_i),
|
||||
.flash_csb_o (s_flash_csb_o),
|
||||
.flash_clk_o (s_flash_clk_o),
|
||||
.flash_io0_oe_o(s_flash_io0_oe),
|
||||
.flash_io1_oe_o(s_flash_io1_oe),
|
||||
.flash_io2_oe_o(s_flash_io2_oe),
|
||||
.flash_io3_oe_o(s_flash_io3_oe),
|
||||
.flash_io0_do_o(s_flash_io0_do),
|
||||
.flash_io1_do_o(s_flash_io1_do),
|
||||
.flash_io2_do_o(s_flash_io2_do),
|
||||
.flash_io3_do_o(s_flash_io3_do),
|
||||
.flash_io0_di_i(s_flash_io0_di),
|
||||
.flash_io1_di_i(s_flash_io1_di),
|
||||
.flash_io2_di_i(s_flash_io2_di),
|
||||
.flash_io3_di_i(s_flash_io3_di),
|
||||
.iomem_valid_o (s_iomem_valid),
|
||||
.iomem_ready_i (r_iomem_ready),
|
||||
.iomem_wstrb_o (s_iomem_wstrb),
|
||||
.iomem_addr_o (s_iomem_addr),
|
||||
.iomem_wdata_o (s_iomem_wdata),
|
||||
.iomem_rdata_i (r_iomem_rdata)
|
||||
);
|
||||
endmodule
|
||||
+1
-1
@@ -49,7 +49,7 @@ module retrosoc_tb;
|
||||
#1 $display("s_leds: %b", s_leds);
|
||||
end
|
||||
|
||||
retrosoc u_retrosoc (
|
||||
retrosoc_asic u_retrosoc (
|
||||
.clk_i (r_clk),
|
||||
.rst_n_i (s_rst_n),
|
||||
.uart_tx_o_pad (s_uart_tx),
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#ifdef RETROSOC
|
||||
# define MEM_TOTAL 0x4000 /* 16 KB */
|
||||
# define MEM_TOTAL 0x10000 /* 64 KB */
|
||||
#else
|
||||
# error "Set -DRETROSOC when compiling firmware.c"
|
||||
#endif
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
|
||||
/*
|
||||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
module spram_model (
|
||||
input clk,
|
||||
input [ 3:0] wen,
|
||||
input [21:0] addr,
|
||||
input [31:0] wdata,
|
||||
output [31:0] rdata
|
||||
);
|
||||
|
||||
wire cs_00, cs_01, cs_10, cs_11;
|
||||
wire [31:0] rdata_00, rdata_01;
|
||||
wire [31:0] rdata_10, rdata_11;
|
||||
|
||||
assign cs_00 = ~addr[11] && ~addr[10];
|
||||
assign cs_01 = ~addr[11] && addr[10];
|
||||
assign cs_10 = addr[11] && ~addr[10];
|
||||
assign cs_11 = addr[11] && addr[10];
|
||||
|
||||
assign rdata = ({32{cs_00}} & rdata_00) | ({32{cs_01}} & rdata_01) |
|
||||
({32{cs_10}} & rdata_10) | ({32{cs_11}} & rdata_11);
|
||||
|
||||
// 4x4KB=16KB
|
||||
// SPRAM1024X32 u_ram00 (
|
||||
tc_sram_1024x32 u_ram00 (
|
||||
.clk_i (clk),
|
||||
.cs_i (cs_00),
|
||||
.addr_i(addr[9:0]),
|
||||
.data_i(wdata),
|
||||
.mask_i(wen),
|
||||
.wren_i(|wen),
|
||||
.data_o(rdata_00)
|
||||
);
|
||||
|
||||
// SPRAM1024X32 u_ram01 (
|
||||
tc_sram_1024x32 u_ram01 (
|
||||
.clk_i (clk),
|
||||
.cs_i (cs_01),
|
||||
.addr_i(addr[9:0]),
|
||||
.data_i(wdata),
|
||||
.mask_i(wen),
|
||||
.wren_i(|wen),
|
||||
.data_o(rdata_01)
|
||||
);
|
||||
|
||||
// SPRAM1024X32 u_ram10 (
|
||||
tc_sram_1024x32 u_ram10 (
|
||||
.clk_i (clk),
|
||||
.cs_i (cs_10),
|
||||
.addr_i(addr[9:0]),
|
||||
.data_i(wdata),
|
||||
.mask_i(wen),
|
||||
.wren_i(|wen),
|
||||
.data_o(rdata_10)
|
||||
);
|
||||
|
||||
// SPRAM1024X32 u_ram11 (
|
||||
tc_sram_1024x32 u_ram11 (
|
||||
.clk_i (clk),
|
||||
.cs_i (cs_11),
|
||||
.addr_i(addr[9:0]),
|
||||
.data_i(wdata),
|
||||
.mask_i(wen),
|
||||
.wren_i(|wen),
|
||||
.data_o(rdata_11)
|
||||
);
|
||||
endmodule
|
||||
|
||||
|
||||
// 4KB
|
||||
module SPRAM1024X32 (
|
||||
input clk_i,
|
||||
input cs_i,
|
||||
input [ 9:0] addr_i,
|
||||
input [31:0] data_i,
|
||||
input [ 3:0] mask_i,
|
||||
input wren_i,
|
||||
output reg [31:0] data_o
|
||||
);
|
||||
reg [31:0] mem[0:1023];
|
||||
always @(posedge clk_i) begin
|
||||
if (cs_i) begin
|
||||
if (!wren_i) begin
|
||||
data_o <= mem[addr_i];
|
||||
end else begin
|
||||
if (mask_i[0]) mem[addr_i][7:0] <= data_i[7:0];
|
||||
if (mask_i[1]) mem[addr_i][15:8] <= data_i[15:8];
|
||||
if (mask_i[2]) mem[addr_i][23:16] <= data_i[23:16];
|
||||
if (mask_i[3]) mem[addr_i][31:24] <= data_i[31:24];
|
||||
data_o <= 32'bx;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Reference in new issue
Block a user