Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full compilation fix #587

Merged
merged 2 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hardware/simulation/sim_build.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Add iob-soc software as a build dependency
#HEX+=iob_soc_preboot.hex iob_soc_boot.hex iob_soc_firmware.hex iob_soc_rom.hex
HEX+=iob_soc_boot.hex iob_soc_firmware.hex

ROOT_DIR :=../..
Expand Down
151 changes: 151 additions & 0 deletions hardware/src/boot_ctr.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
`timescale 1 ns / 1 ps

module boot_ctr #(
parameter HEXFILE = "iob_soc_boot.hex",
parameter DATA_W = 0,
parameter ADDR_W = 0,
parameter BOOTROM_ADDR_W = 0,
parameter SRAM_ADDR_W = 0
) (
output cpu_rst,
output boot,

//cpu interface
input cpu_avalid,
input [ 1:0] cpu_wdata,
input [DATA_W/8-1:0] cpu_wstrb,
output [ DATA_W-1:0] cpu_rdata,
output reg cpu_rvalid,
output reg cpu_ready,


//sram master write interface
output reg sram_avalid,
output [ ADDR_W-1:0] sram_addr,
output [ DATA_W-1:0] sram_wdata,
output reg [DATA_W/8-1:0] sram_wstrb,

`include "clk_en_rst_s_port.vs"
);


//cpu interface: rdata and ready
assign cpu_rdata = {{(DATA_W - 1) {1'b0}}, boot};
iob_reg #(
.DATA_W (1),
.RST_VAL(0)
) rvalid_reg (
.clk_i (clk_i),
.arst_i(arst_i),
.cke_i (cke_i),
.data_i(cpu_avalid & ~(|cpu_wstrb)),
.data_o(cpu_rvalid)
);
assign cpu_ready = 1'b1;

//boot register: (1) load bootloader to sram and run it: (0) run program
wire boot_wr = cpu_avalid & |cpu_wstrb;
reg boot_nxt;
iob_reg_re #(
.DATA_W (1),
.RST_VAL(1)
) bootnxt (
.clk_i (clk_i),
.arst_i(arst_i),
.cke_i (cke_i),
.rst_i (1'b0),
.en_i (boot_wr),
.data_i(cpu_wdata[0]),
.data_o(boot_nxt)
);
iob_reg_r #(
.DATA_W (1),
.RST_VAL(1)
) bootreg (
.clk_i (clk_i),
.arst_i(arst_i),
.cke_i (cke_i),
.rst_i (1'b0),
.data_i(boot_nxt),
.data_o(boot)
);


//create CPU reset pulse
wire cpu_rst_req;
assign cpu_rst_req = cpu_avalid & (|cpu_wstrb) & cpu_wdata[1];
wire cpu_rst_pulse;

iob_pulse_gen #(
.START (0),
.DURATION(100)
) reset_pulse (
.clk_i (clk_i),
.arst_i (arst_i),
.cke_i (cke_i),
.start_i(cpu_rst_req),
.pulse_o(cpu_rst_pulse)
);

wire loading;
assign cpu_rst = loading | cpu_rst_pulse;

//
// READ BOOT ROM
//
reg rom_r_avalid;
reg [BOOTROM_ADDR_W-3:0] rom_r_addr;
wire [ DATA_W-1:0] rom_r_rdata;

always @(posedge clk_i, posedge arst_i)
if (arst_i) begin
rom_r_avalid <= 1'b1;
rom_r_addr <= {(BOOTROM_ADDR_W - 2) {1'b0}};
end else if (boot && rom_r_addr != (2 ** (BOOTROM_ADDR_W - 2) - 1))
rom_r_addr <= rom_r_addr + 1'b1;
else begin
rom_r_avalid <= 1'b0;
rom_r_addr <= {(BOOTROM_ADDR_W - 2) {1'b0}};
end

//
// WRITE SRAM
//
reg sram_w_avalid;
reg [SRAM_ADDR_W-2-1:0] sram_w_addr;
always @(posedge clk_i, posedge arst_i)
if (arst_i) begin
sram_w_avalid <= 1'b0;
sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}};
sram_wstrb <= {DATA_W / 8{1'b1}};
end else if (boot) begin
sram_w_avalid <= rom_r_avalid;
sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}} + rom_r_addr;
sram_wstrb <= {DATA_W / 8{rom_r_avalid}};
end else begin
sram_w_avalid <= 1'b0;
sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}};
sram_wstrb <= {DATA_W / 8{1'b1}};
end

assign loading = rom_r_avalid | sram_w_avalid;

assign sram_avalid = sram_w_avalid;
assign sram_addr = {sram_w_addr, 2'b00};
assign sram_wdata = rom_r_rdata;

//
//INSTANTIATE ROM
//
iob_rom_sp #(
.DATA_W (DATA_W),
.ADDR_W (BOOTROM_ADDR_W - 2),
.HEXFILE(HEXFILE)
) sp_rom0 (
.clk_i (clk_i),
.r_en_i (rom_r_avalid),
.addr_i (rom_r_addr),
.r_data_o(rom_r_rdata)
);

endmodule
206 changes: 206 additions & 0 deletions hardware/src/ext_mem.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
`timescale 1 ns / 1 ps

`include "iob_utils.vh"

module ext_mem #(
parameter ADDR_W = 0,
parameter DATA_W = 0,
parameter FIRM_ADDR_W = 0,
parameter MEM_ADDR_W = 0,
parameter DDR_ADDR_W = 0,
parameter DDR_DATA_W = 0,
parameter AXI_ID_W = 0,
parameter AXI_LEN_W = 0,
parameter AXI_ADDR_W = 0,
parameter AXI_DATA_W = 0
) (
// Instruction bus
input [1+FIRM_ADDR_W-2+`WRITE_W-1:0] i_req,
output [ `RESP_W-1:0] i_resp,

// Data bus
input [1+1+MEM_ADDR_W-2+`WRITE_W-1:0] d_req,
output [ `RESP_W-1:0] d_resp,

// AXI interface
`include "axi_m_port.vs"
`include "clk_en_rst_s_port.vs"
);

//
// INSTRUCTION CACHE
//

// Back-end bus
wire [1+MEM_ADDR_W+`WRITE_W-1:0] icache_be_req;
wire [ `RESP_W-1:0] icache_be_resp;


// Instruction cache instance
iob_cache_iob #(
.FE_ADDR_W (FIRM_ADDR_W),
.BE_ADDR_W (MEM_ADDR_W),
.NWAYS_W (1), //Number of ways
.NLINES_W (7), //Cache Line Offset (number of lines)
.WORD_OFFSET_W(3), //Word Offset (number of words per line)
.WTBUF_DEPTH_W(5), //FIFO's depth -- 5 minimum for BRAM implementation
.USE_CTRL (0), //Cache-Control can't be accessed
.USE_CTRL_CNT (0) //Remove counters
) icache (
.clk_i (clk_i),
.cke_i (cke_i),
.arst_i(arst_i),

// Front-end interface
.avalid_i (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]),
.addr_i (i_req[`ADDRESS(0, FIRM_ADDR_W-2)]),
.wdata_i (i_req[`WDATA(0)]),
.wstrb_i (i_req[`WSTRB(0)]),
.rdata_o (i_resp[`RDATA(0)]),
.rvalid_o (i_resp[`RVALID(0)]),
.ready_o (i_resp[`READY(0)]),
//Control IO
.invalidate_i (1'b0),
.invalidate_o(),
.wtb_empty_i (1'b1),
.wtb_empty_o (),
// Back-end interface
.be_avalid_o (icache_be_req[1+MEM_ADDR_W+`WRITE_W-1]),
.be_addr_o (icache_be_req[`ADDRESS(0, MEM_ADDR_W)]),
.be_wdata_o (icache_be_req[`WDATA(0)]),
.be_wstrb_o (icache_be_req[`WSTRB(0)]),
.be_rdata_i (icache_be_resp[`RDATA(0)]),
.be_rvalid_i (icache_be_resp[`RVALID(0)]),
.be_ready_i (icache_be_resp[`READY(0)])
);

//l2 cache interface signals
wire [1+MEM_ADDR_W+`WRITE_W-1:0] l2cache_req;
wire [`RESP_W-1:0] l2cache_resp;

//ext_mem control signals
wire l2_wtb_empty;
wire invalidate;
reg invalidate_reg;
wire l2_avalid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1];
//Necessary logic to avoid invalidating L2 while it's being accessed by a request
always @(posedge clk_i, posedge arst_i)
if (arst_i) invalidate_reg <= 1'b0;
else if (invalidate) invalidate_reg <= 1'b1;
else if (~l2_avalid) invalidate_reg <= 1'b0;
else invalidate_reg <= invalidate_reg;

//
// DATA CACHE
//

// IOb ready and rvalid signals

// Back-end bus
wire [1+MEM_ADDR_W+`WRITE_W-1:0] dcache_be_req;
wire [ `RESP_W-1:0] dcache_be_resp;

// Data cache instance
iob_cache_iob #(
.FE_ADDR_W (MEM_ADDR_W),
.BE_ADDR_W (MEM_ADDR_W),
.NWAYS_W (1), //Number of ways
.NLINES_W (7), //Cache Line Offset (number of lines)
.WORD_OFFSET_W(3), //Word Offset (number of words per line)
.WTBUF_DEPTH_W(5), //FIFO's depth -- 5 minimum for BRAM implementation
.USE_CTRL (1), //Either 1 to enable cache-control or 0 to disable
.USE_CTRL_CNT (1) //do not change (it's implementation depends on the previous)
) dcache (
.clk_i (clk_i),
.cke_i (cke_i),
.arst_i(arst_i),

// Front-end interface
.avalid_i (d_req[2+MEM_ADDR_W-2+`WRITE_W-1]),
.addr_i (d_req[`ADDRESS(0, 1+MEM_ADDR_W-2)]),
.wdata_i (d_req[`WDATA(0)]),
.wstrb_i (d_req[`WSTRB(0)]),
.rdata_o (d_resp[`RDATA(0)]),
.rvalid_o (d_resp[`RVALID(0)]),
.ready_o (d_resp[`READY(0)]),
//Control IO
.invalidate_i (1'b0),
.invalidate_o(invalidate),
.wtb_empty_i (l2_wtb_empty),
.wtb_empty_o (),
// Back-end interface
.be_avalid_o (dcache_be_req[1+MEM_ADDR_W+`WRITE_W-1]),
.be_addr_o (dcache_be_req[`ADDRESS(0, MEM_ADDR_W)]),
.be_wdata_o (dcache_be_req[`WDATA(0)]),
.be_wstrb_o (dcache_be_req[`WSTRB(0)]),
.be_rdata_i (dcache_be_resp[`RDATA(0)]),
.be_rvalid_i (dcache_be_resp[`RVALID(0)]),
.be_ready_i (dcache_be_resp[`READY(0)])
);

// Merge cache back-ends
iob_merge #(
.ADDR_W (MEM_ADDR_W),
.N_MASTERS(2)
) merge_i_d_buses_into_l2 (
.clk_i (clk_i),
.arst_i (arst_i),
// masters
.m_req_i ({icache_be_req, dcache_be_req}),
.m_resp_o({icache_be_resp, dcache_be_resp}),
// slave
.s_req_o (l2cache_req),
.s_resp_i(l2cache_resp)
);

wire l2cache_valid;
wire [MEM_ADDR_W-3:0] l2cache_addr;
wire [ DATA_W-1:0] l2cache_wdata;
wire [ DATA_W/8-1:0] l2cache_wstrb;
wire [ DATA_W-1:0] l2cache_rdata;
wire l2cache_rvalid;
wire l2cache_ready;

assign l2cache_valid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1];
assign l2cache_addr = l2cache_req[`ADDRESS(0, MEM_ADDR_W)-2];
assign l2cache_wdata = l2cache_req[`WDATA(0)];
assign l2cache_wstrb = l2cache_req[`WSTRB(0)];
assign l2cache_resp[`RDATA(0)] = l2cache_rdata;
assign l2cache_resp[`RVALID(0)] = l2cache_rvalid;
assign l2cache_resp[`READY(0)] = l2cache_ready;

// L2 cache instance
iob_cache_axi #(
.AXI_ID_W (AXI_ID_W),
.AXI_LEN_W (AXI_LEN_W),
.FE_ADDR_W (MEM_ADDR_W),
.BE_ADDR_W (DDR_ADDR_W),
.BE_DATA_W (DDR_DATA_W),
.NWAYS_W (2), //Number of Ways
.NLINES_W (7), //Cache Line Offset (number of lines)
.WORD_OFFSET_W(3), //Word Offset (number of words per line)
.WTBUF_DEPTH_W(5), //FIFO's depth -- 5 minimum for BRAM implementation
.USE_CTRL (0), //Cache-Control can't be accessed
.USE_CTRL_CNT (0) //Remove counters
) l2cache (
// Native interface
.avalid_i (l2cache_valid),
.addr_i (l2cache_addr),
.wdata_i (l2cache_wdata),
.wstrb_i (l2cache_wstrb),
.rdata_o (l2cache_rdata),
.rvalid_o (l2cache_rvalid),
.ready_o (l2cache_ready),
//Control IO
.invalidate_i (invalidate_reg & ~l2_avalid),
.invalidate_o(),
.wtb_empty_i (1'b1),
.wtb_empty_o (l2_wtb_empty),
// AXI interface
`include "axi_m_m_portmap.vs"
.clk_i (clk_i),
.cke_i (cke_i),
.arst_i (arst_i)
);

endmodule
Loading
Loading