Folder rename
This commit is contained in:
480
src_ref/top/scr1_dmem_ahb.sv
Normal file
480
src_ref/top/scr1_dmem_ahb.sv
Normal file
@@ -0,0 +1,480 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_dmem_ahb.sv>
|
||||
/// @brief Data memory AHB bridge
|
||||
///
|
||||
|
||||
`include "scr1_ahb.svh"
|
||||
`include "scr1_memif.svh"
|
||||
|
||||
module scr1_dmem_ahb (
|
||||
// Control Signals
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
|
||||
// Core Interface
|
||||
output logic dmem_req_ack,
|
||||
input logic dmem_req,
|
||||
input type_scr1_mem_cmd_e dmem_cmd,
|
||||
input type_scr1_mem_width_e dmem_width,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] dmem_addr,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] dmem_wdata,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] dmem_rdata,
|
||||
output type_scr1_mem_resp_e dmem_resp,
|
||||
|
||||
// AHB Interface
|
||||
output logic [3:0] hprot,
|
||||
output logic [2:0] hburst,
|
||||
output logic [2:0] hsize,
|
||||
output logic [1:0] htrans,
|
||||
output logic hmastlock,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] haddr,
|
||||
output logic hwrite,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] hwdata,
|
||||
input logic hready,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] hrdata,
|
||||
input logic hresp
|
||||
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local Parameters
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifndef SCR1_DMEM_AHB_OUT_BP
|
||||
localparam SCR1_FIFO_WIDTH = 2;
|
||||
localparam SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
|
||||
`endif // SCR1_DMEM_AHB_OUT_BP
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local type declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
typedef enum logic {
|
||||
SCR1_FSM_ADDR = 1'b0,
|
||||
SCR1_FSM_DATA = 1'b1
|
||||
`ifdef SCR1_XPROP_EN
|
||||
,
|
||||
SCR1_FSM_ERR = 1'bx
|
||||
`endif // SCR1_XPROP_EN
|
||||
} type_scr1_fsm_e;
|
||||
|
||||
typedef struct packed {
|
||||
logic hwrite;
|
||||
logic [2:0] hwidth;
|
||||
logic [SCR1_AHB_WIDTH-1:0] haddr;
|
||||
logic [SCR1_AHB_WIDTH-1:0] hwdata;
|
||||
} type_scr1_req_fifo_s;
|
||||
|
||||
typedef struct packed {
|
||||
logic [2:0] hwidth;
|
||||
logic [1:0] haddr;
|
||||
logic [SCR1_AHB_WIDTH-1:0] hwdata;
|
||||
} type_scr1_data_fifo_s;
|
||||
|
||||
typedef struct packed {
|
||||
logic hresp;
|
||||
logic [2:0] hwidth;
|
||||
logic [1:0] haddr;
|
||||
logic [SCR1_AHB_WIDTH-1:0] hrdata;
|
||||
} type_scr1_resp_fifo_s;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local functions
|
||||
//-------------------------------------------------------------------------------
|
||||
function automatic logic [2:0] scr1_conv_mem2ahb_width (
|
||||
input type_scr1_mem_width_e dmem_width
|
||||
);
|
||||
logic [2:0] tmp;
|
||||
begin
|
||||
case (dmem_width)
|
||||
SCR1_MEM_WIDTH_BYTE : begin
|
||||
tmp = SCR1_HSIZE_8B;
|
||||
end
|
||||
SCR1_MEM_WIDTH_HWORD : begin
|
||||
tmp = SCR1_HSIZE_16B;
|
||||
end
|
||||
SCR1_MEM_WIDTH_WORD : begin
|
||||
tmp = SCR1_HSIZE_32B;
|
||||
end
|
||||
default : begin
|
||||
tmp = SCR1_HSIZE_ERR;
|
||||
end
|
||||
endcase
|
||||
return tmp;
|
||||
end
|
||||
endfunction : scr1_conv_mem2ahb_width
|
||||
|
||||
function automatic logic[SCR1_AHB_WIDTH-1:0] scr1_conv_mem2ahb_wdata (
|
||||
input logic [1:0] dmem_addr,
|
||||
input type_scr1_mem_width_e dmem_width,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] dmem_wdata
|
||||
);
|
||||
logic [SCR1_AHB_WIDTH-1:0] tmp;
|
||||
begin
|
||||
`ifdef SCR1_XPROP_EN
|
||||
tmp = 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
tmp = '0;
|
||||
`endif // SCR1_XPROP_EN
|
||||
case (dmem_width)
|
||||
SCR1_MEM_WIDTH_BYTE : begin
|
||||
case (dmem_addr)
|
||||
2'b00 : begin
|
||||
tmp[7:0] = dmem_wdata[7:0];
|
||||
end
|
||||
2'b01 : begin
|
||||
tmp[15:8] = dmem_wdata[7:0];
|
||||
end
|
||||
2'b10 : begin
|
||||
tmp[23:16] = dmem_wdata[7:0];
|
||||
end
|
||||
2'b11 : begin
|
||||
tmp[31:24] = dmem_wdata[7:0];
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SCR1_MEM_WIDTH_HWORD : begin
|
||||
case (dmem_addr[1])
|
||||
1'b0 : begin
|
||||
tmp[15:0] = dmem_wdata[15:0];
|
||||
end
|
||||
1'b1 : begin
|
||||
tmp[31:16] = dmem_wdata[15:0];
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SCR1_MEM_WIDTH_WORD : begin
|
||||
tmp = dmem_wdata;
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
return tmp;
|
||||
end
|
||||
endfunction : scr1_conv_mem2ahb_wdata
|
||||
|
||||
function automatic logic[SCR1_AHB_WIDTH-1:0] scr1_conv_ahb2mem_rdata (
|
||||
input logic [2:0] hwidth,
|
||||
input logic [1:0] haddr,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] hrdata
|
||||
);
|
||||
logic [SCR1_AHB_WIDTH-1:0] tmp;
|
||||
begin
|
||||
`ifdef SCR1_XPROP_EN
|
||||
tmp = 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
tmp = '0;
|
||||
`endif // SCR1_XPROP_EN
|
||||
case (hwidth)
|
||||
SCR1_HSIZE_8B : begin
|
||||
case (haddr)
|
||||
2'b00 : tmp[7:0] = hrdata[7:0];
|
||||
2'b01 : tmp[7:0] = hrdata[15:8];
|
||||
2'b10 : tmp[7:0] = hrdata[23:16];
|
||||
2'b11 : tmp[7:0] = hrdata[31:24];
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SCR1_HSIZE_16B : begin
|
||||
case (haddr[1])
|
||||
1'b0 : tmp[15:0] = hrdata[15:0];
|
||||
1'b1 : tmp[15:0] = hrdata[31:16];
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SCR1_HSIZE_32B : begin
|
||||
tmp = hrdata;
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
return tmp;
|
||||
end
|
||||
endfunction : scr1_conv_ahb2mem_rdata
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
type_scr1_fsm_e fsm;
|
||||
logic req_fifo_rd;
|
||||
logic req_fifo_wr;
|
||||
logic req_fifo_up;
|
||||
`ifdef SCR1_DMEM_AHB_OUT_BP
|
||||
type_scr1_req_fifo_s req_fifo_new;
|
||||
type_scr1_req_fifo_s req_fifo_r;
|
||||
type_scr1_req_fifo_s [0:0] req_fifo;
|
||||
`else // SCR1_DMEM_AHB_OUT_BP
|
||||
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo;
|
||||
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo_new;
|
||||
logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt;
|
||||
logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt_new;
|
||||
`endif // SCR1_DMEM_AHB_OUT_BP
|
||||
logic req_fifo_empty;
|
||||
logic req_fifo_full;
|
||||
|
||||
type_scr1_data_fifo_s data_fifo;
|
||||
type_scr1_resp_fifo_s resp_fifo;
|
||||
logic resp_fifo_hready;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to Core
|
||||
//-------------------------------------------------------------------------------
|
||||
assign dmem_req_ack = ~req_fifo_full;
|
||||
assign req_fifo_wr = ~req_fifo_full & dmem_req;
|
||||
|
||||
assign dmem_rdata = scr1_conv_ahb2mem_rdata(resp_fifo.hwidth, resp_fifo.haddr, resp_fifo.hrdata);
|
||||
|
||||
assign dmem_resp = (resp_fifo_hready)
|
||||
? (resp_fifo.hresp == SCR1_HRESP_OKAY)
|
||||
? SCR1_MEM_RESP_RDY_OK
|
||||
: SCR1_MEM_RESP_RDY_ER
|
||||
: SCR1_MEM_RESP_NOTRDY ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// REQ_FIFO
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_DMEM_AHB_OUT_BP
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_fifo_full <= 1'b0;
|
||||
end else begin
|
||||
if (~req_fifo_full) begin
|
||||
req_fifo_full <= dmem_req & ~req_fifo_rd;
|
||||
end else begin
|
||||
req_fifo_full <= ~req_fifo_rd;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign req_fifo_empty = ~(req_fifo_full | dmem_req);
|
||||
|
||||
assign req_fifo_up = ~req_fifo_rd & req_fifo_wr;
|
||||
always_ff @(posedge clk) begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo_r <= req_fifo_new;
|
||||
end
|
||||
end
|
||||
|
||||
assign req_fifo_new.hwrite = dmem_req ? (dmem_cmd == SCR1_MEM_CMD_WR) : 1'b0;
|
||||
assign req_fifo_new.hwidth = dmem_req ? scr1_conv_mem2ahb_width(dmem_width) : '0;
|
||||
assign req_fifo_new.haddr = dmem_req ? dmem_addr : '0;
|
||||
assign req_fifo_new.hwdata = (dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR))
|
||||
? scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata)
|
||||
: '0;
|
||||
assign req_fifo[0] = (req_fifo_full) ? req_fifo_r: req_fifo_new;
|
||||
|
||||
`else // SCR1_DMEM_AHB_OUT_BP
|
||||
always_comb begin
|
||||
req_fifo_up = 1'b0;
|
||||
req_fifo_cnt_new = req_fifo_cnt;
|
||||
req_fifo_new = req_fifo;
|
||||
case ({req_fifo_rd, req_fifo_wr})
|
||||
2'b00 : begin
|
||||
// nothing todo
|
||||
end
|
||||
2'b01: begin
|
||||
// FIFO write
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[req_fifo_cnt].hwrite = (dmem_cmd == SCR1_MEM_CMD_WR);
|
||||
req_fifo_new[req_fifo_cnt].hwidth = scr1_conv_mem2ahb_width(dmem_width);
|
||||
req_fifo_new[req_fifo_cnt].haddr = dmem_addr;
|
||||
req_fifo_new[req_fifo_cnt].hwdata = scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata);
|
||||
req_fifo_cnt_new = req_fifo_cnt + 1'b1;
|
||||
end
|
||||
2'b10 : begin
|
||||
// FIFO read
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[0] = req_fifo_new[1];
|
||||
req_fifo_new[1].hwrite = 1'b0;
|
||||
req_fifo_new[1].hwidth = SCR1_HSIZE_32B;
|
||||
`ifdef SCR1_XPROP_EN
|
||||
req_fifo_new[1].haddr = 'x;
|
||||
req_fifo_new[1].hwdata = 'x;
|
||||
`endif // SCR1_XPROP_EN
|
||||
req_fifo_cnt_new = req_fifo_cnt - 1'b1;
|
||||
end
|
||||
2'b11 : begin
|
||||
// Read and Write FIFO. It is possible only when fifo_cnt = 1
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[0].hwrite = (dmem_cmd == SCR1_MEM_CMD_WR);
|
||||
req_fifo_new[0].hwidth = scr1_conv_mem2ahb_width(dmem_width);
|
||||
req_fifo_new[0].haddr = dmem_addr;
|
||||
req_fifo_new[0].hwdata = scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata);
|
||||
end
|
||||
default : begin
|
||||
`ifdef SCR1_XPROP_EN
|
||||
req_fifo_up = 'x;
|
||||
req_fifo_cnt_new = 'x;
|
||||
req_fifo_new = 'x;
|
||||
`endif // SCR1_XPROP_EN
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_fifo_cnt <= '0;
|
||||
end else begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo_cnt <= req_fifo_cnt_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign req_fifo_full = (req_fifo_cnt == SCR1_FIFO_WIDTH);
|
||||
assign req_fifo_empty = ~(|req_fifo_cnt);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo <= req_fifo_new;
|
||||
end
|
||||
end
|
||||
`endif // SCR1_DMEM_AHB_OUT_BP
|
||||
//-------------------------------------------------------------------------------
|
||||
// FSM
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end else begin
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (hready) begin
|
||||
fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
if (hresp == SCR1_HRESP_OKAY) begin
|
||||
fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
|
||||
end else begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
`ifdef SCR1_XPROP_EN
|
||||
fsm <= SCR1_FSM_ERR;
|
||||
`endif // SCR1_XPROP_EN
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
req_fifo_rd = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (hready) begin
|
||||
req_fifo_rd = ~req_fifo_empty;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
req_fifo_rd = 1'bx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FIFO data
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(posedge clk) begin
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (~req_fifo_empty) begin
|
||||
data_fifo.hwidth <= req_fifo[0].hwidth;
|
||||
data_fifo.haddr <= req_fifo[0].haddr[1:0];
|
||||
data_fifo.hwdata <= req_fifo[0].hwdata;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
if (hresp == SCR1_HRESP_OKAY) begin
|
||||
if (~req_fifo_empty) begin
|
||||
data_fifo.hwidth <= req_fifo[0].hwidth;
|
||||
data_fifo.haddr <= req_fifo[0].haddr[1:0];
|
||||
data_fifo.hwdata <= req_fifo[0].hwdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FIFO response
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_DMEM_AHB_IN_BP
|
||||
assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
|
||||
assign resp_fifo.hresp = hresp;
|
||||
assign resp_fifo.hwidth = data_fifo.hwidth;
|
||||
assign resp_fifo.haddr = data_fifo.haddr;
|
||||
assign resp_fifo.hrdata = hrdata;
|
||||
`else // SCR1_DMEM_AHB_IN_BP
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
resp_fifo_hready <= 1'b0;
|
||||
end else begin
|
||||
resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (hready & (fsm == SCR1_FSM_DATA)) begin
|
||||
resp_fifo.hresp <= hresp;
|
||||
resp_fifo.hwidth <= data_fifo.hwidth;
|
||||
resp_fifo.haddr <= data_fifo.haddr;
|
||||
resp_fifo.hrdata <= hrdata;
|
||||
end
|
||||
end
|
||||
`endif // SCR1_DMEM_AHB_IN_BP
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to AHB
|
||||
//-------------------------------------------------------------------------------
|
||||
assign hprot[SCR1_HPROT_DATA] = 1'b1;
|
||||
assign hprot[SCR1_HPROT_PRV] = 1'b0;
|
||||
assign hprot[SCR1_HPROT_BUF] = 1'b0;
|
||||
assign hprot[SCR1_HPROT_CACHE] = 1'b0;
|
||||
|
||||
assign hburst = SCR1_HBURST_SINGLE;
|
||||
assign hsize = req_fifo[0].hwidth;
|
||||
assign hmastlock = 1'b0;
|
||||
|
||||
always_comb begin
|
||||
htrans = SCR1_HTRANS_IDLE;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (~req_fifo_empty) begin
|
||||
htrans = SCR1_HTRANS_NONSEQ;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
if (hresp == SCR1_HRESP_OKAY) begin
|
||||
if (~req_fifo_empty) begin
|
||||
htrans = SCR1_HTRANS_NONSEQ;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
htrans = SCR1_HTRANS_ERR;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign haddr = req_fifo[0].haddr;
|
||||
assign hwrite = req_fifo[0].hwrite;
|
||||
assign hwdata = data_fifo.hwdata;
|
||||
|
||||
endmodule : scr1_dmem_ahb
|
||||
278
src_ref/top/scr1_dmem_router.sv
Normal file
278
src_ref/top/scr1_dmem_router.sv
Normal file
@@ -0,0 +1,278 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_dmem_router.sv>
|
||||
/// @brief Data memory router
|
||||
///
|
||||
`include "scr1_memif.svh"
|
||||
`include "scr1_arch_description.svh"
|
||||
|
||||
module scr1_dmem_router
|
||||
#(
|
||||
parameter SCR1_PORT1_ADDR_MASK = `SCR1_DMEM_AWIDTH'hFFFF0000,
|
||||
parameter SCR1_PORT1_ADDR_PATTERN = `SCR1_DMEM_AWIDTH'h00010000,
|
||||
parameter SCR1_PORT2_ADDR_MASK = `SCR1_DMEM_AWIDTH'hFFFF0000,
|
||||
parameter SCR1_PORT2_ADDR_PATTERN = `SCR1_DMEM_AWIDTH'h00020000
|
||||
)
|
||||
(
|
||||
// Control signals
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
|
||||
// Core interface
|
||||
output logic dmem_req_ack,
|
||||
input logic dmem_req,
|
||||
input type_scr1_mem_cmd_e dmem_cmd,
|
||||
input type_scr1_mem_width_e dmem_width,
|
||||
input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata,
|
||||
output type_scr1_mem_resp_e dmem_resp,
|
||||
|
||||
// PORT0 interface
|
||||
input logic port0_req_ack,
|
||||
output logic port0_req,
|
||||
output type_scr1_mem_cmd_e port0_cmd,
|
||||
output type_scr1_mem_width_e port0_width,
|
||||
output logic [`SCR1_DMEM_AWIDTH-1:0] port0_addr,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] port0_wdata,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] port0_rdata,
|
||||
input type_scr1_mem_resp_e port0_resp,
|
||||
|
||||
// PORT1 interface
|
||||
input logic port1_req_ack,
|
||||
output logic port1_req,
|
||||
output type_scr1_mem_cmd_e port1_cmd,
|
||||
output type_scr1_mem_width_e port1_width,
|
||||
output logic [`SCR1_DMEM_AWIDTH-1:0] port1_addr,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] port1_wdata,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] port1_rdata,
|
||||
input type_scr1_mem_resp_e port1_resp,
|
||||
|
||||
// PORT2 interface
|
||||
input logic port2_req_ack,
|
||||
output logic port2_req,
|
||||
output type_scr1_mem_cmd_e port2_cmd,
|
||||
output type_scr1_mem_width_e port2_width,
|
||||
output logic [`SCR1_DMEM_AWIDTH-1:0] port2_addr,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] port2_wdata,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] port2_rdata,
|
||||
input type_scr1_mem_resp_e port2_resp
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local types declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
typedef enum logic {
|
||||
SCR1_FSM_ADDR,
|
||||
SCR1_FSM_DATA
|
||||
} type_scr1_fsm_e;
|
||||
|
||||
typedef enum logic [1:0] {
|
||||
SCR1_SEL_PORT0,
|
||||
SCR1_SEL_PORT1,
|
||||
SCR1_SEL_PORT2
|
||||
} type_scr1_sel_e;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
type_scr1_fsm_e fsm;
|
||||
type_scr1_sel_e port_sel;
|
||||
type_scr1_sel_e port_sel_r;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] sel_rdata;
|
||||
type_scr1_mem_resp_e sel_resp;
|
||||
logic sel_req_ack;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FSM
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port_sel = SCR1_SEL_PORT0;
|
||||
if ((dmem_addr & SCR1_PORT1_ADDR_MASK) == SCR1_PORT1_ADDR_PATTERN) begin
|
||||
port_sel = SCR1_SEL_PORT1;
|
||||
end else if ((dmem_addr & SCR1_PORT2_ADDR_MASK) == SCR1_PORT2_ADDR_PATTERN) begin
|
||||
port_sel = SCR1_SEL_PORT2;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
port_sel_r <= SCR1_SEL_PORT0;
|
||||
end else begin
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (dmem_req & sel_req_ack) begin
|
||||
fsm <= SCR1_FSM_DATA;
|
||||
port_sel_r <= port_sel;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
case (sel_resp)
|
||||
SCR1_MEM_RESP_RDY_OK : begin
|
||||
if (dmem_req & sel_req_ack) begin
|
||||
fsm <= SCR1_FSM_DATA;
|
||||
port_sel_r <= port_sel;
|
||||
end else begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
end
|
||||
SCR1_MEM_RESP_RDY_ER : begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin
|
||||
case (port_sel)
|
||||
SCR1_SEL_PORT0 : sel_req_ack = port0_req_ack;
|
||||
SCR1_SEL_PORT1 : sel_req_ack = port1_req_ack;
|
||||
SCR1_SEL_PORT2 : sel_req_ack = port2_req_ack;
|
||||
default : sel_req_ack = 1'b0;
|
||||
endcase
|
||||
end else begin
|
||||
sel_req_ack = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (port_sel_r)
|
||||
SCR1_SEL_PORT0 : begin
|
||||
sel_rdata = port0_rdata;
|
||||
sel_resp = port0_resp;
|
||||
end
|
||||
SCR1_SEL_PORT1 : begin
|
||||
sel_rdata = port1_rdata;
|
||||
sel_resp = port1_resp;
|
||||
end
|
||||
SCR1_SEL_PORT2 : begin
|
||||
sel_rdata = port2_rdata;
|
||||
sel_resp = port2_resp;
|
||||
end
|
||||
default : begin
|
||||
sel_rdata = '0;
|
||||
sel_resp = SCR1_MEM_RESP_RDY_ER;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to core
|
||||
//-------------------------------------------------------------------------------
|
||||
assign dmem_req_ack = sel_req_ack;
|
||||
assign dmem_rdata = sel_rdata;
|
||||
assign dmem_resp = sel_resp;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to PORT0
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port0_req = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
|
||||
port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef SCR1_XPROP_EN
|
||||
assign port0_cmd = (port_sel == SCR1_SEL_PORT0) ? dmem_cmd : SCR1_MEM_CMD_ERROR;
|
||||
assign port0_width = (port_sel == SCR1_SEL_PORT0) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
|
||||
assign port0_addr = (port_sel == SCR1_SEL_PORT0) ? dmem_addr : 'x;
|
||||
assign port0_wdata = (port_sel == SCR1_SEL_PORT0) ? dmem_wdata : 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
assign port0_cmd = dmem_cmd ;
|
||||
assign port0_width = dmem_width;
|
||||
assign port0_addr = dmem_addr ;
|
||||
assign port0_wdata = dmem_wdata;
|
||||
`endif // SCR1_XPROP_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to PORT1
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port1_req = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
|
||||
port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef SCR1_XPROP_EN
|
||||
assign port1_cmd = (port_sel == SCR1_SEL_PORT1) ? dmem_cmd : SCR1_MEM_CMD_ERROR;
|
||||
assign port1_width = (port_sel == SCR1_SEL_PORT1) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
|
||||
assign port1_addr = (port_sel == SCR1_SEL_PORT1) ? dmem_addr : 'x;
|
||||
assign port1_wdata = (port_sel == SCR1_SEL_PORT1) ? dmem_wdata : 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
assign port1_cmd = dmem_cmd ;
|
||||
assign port1_width = dmem_width;
|
||||
assign port1_addr = dmem_addr ;
|
||||
assign port1_wdata = dmem_wdata;
|
||||
`endif // SCR1_XPROP_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to PORT2
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port2_req = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
|
||||
port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef SCR1_XPROP_EN
|
||||
assign port2_cmd = (port_sel == SCR1_SEL_PORT2) ? dmem_cmd : SCR1_MEM_CMD_ERROR;
|
||||
assign port2_width = (port_sel == SCR1_SEL_PORT2) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
|
||||
assign port2_addr = (port_sel == SCR1_SEL_PORT2) ? dmem_addr : 'x;
|
||||
assign port2_wdata = (port_sel == SCR1_SEL_PORT2) ? dmem_wdata : 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
assign port2_cmd = dmem_cmd ;
|
||||
assign port2_width = dmem_width;
|
||||
assign port2_addr = dmem_addr ;
|
||||
assign port2_wdata = dmem_wdata;
|
||||
`endif // SCR1_XPROP_EN
|
||||
|
||||
`ifdef SCR1_TRGT_SIMULATION
|
||||
//-------------------------------------------------------------------------------
|
||||
// Assertion
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
SCR1_SVA_DMEM_RT_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
dmem_req |-> !$isunknown({port_sel, dmem_cmd, dmem_width})
|
||||
) else $error("DMEM router Error: unknown values");
|
||||
|
||||
`endif // SCR1_TRGT_SIMULATION
|
||||
|
||||
endmodule : scr1_dmem_router
|
||||
111
src_ref/top/scr1_dp_memory.sv
Normal file
111
src_ref/top/scr1_dp_memory.sv
Normal file
@@ -0,0 +1,111 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
||||
/// @file <scr1_dp_memory.sv>
|
||||
/// @brief Dual-port synchronous memory with byte enable inputs
|
||||
///
|
||||
|
||||
`include "scr1_arch_description.svh"
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
module scr1_dp_memory
|
||||
#(
|
||||
parameter SCR1_WIDTH = 32,
|
||||
parameter SCR1_SIZE = `SCR1_IMEM_AWIDTH'h00010000,
|
||||
parameter SCR1_NBYTES = SCR1_WIDTH / 8
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
// Port A
|
||||
input logic rena,
|
||||
input logic [$clog2(SCR1_SIZE)-1:2] addra,
|
||||
output logic [SCR1_WIDTH-1:0] qa,
|
||||
// Port B
|
||||
input logic renb,
|
||||
input logic wenb,
|
||||
input logic [SCR1_NBYTES-1:0] webb,
|
||||
input logic [$clog2(SCR1_SIZE)-1:2] addrb,
|
||||
input logic [SCR1_WIDTH-1:0] datab,
|
||||
output logic [SCR1_WIDTH-1:0] qb
|
||||
);
|
||||
|
||||
`ifdef SCR1_TRGT_FPGA_INTEL
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_TRGT_FPGA_INTEL_MAX10
|
||||
(* ramstyle = "M9K" *) logic [SCR1_NBYTES-1:0][7:0] memory_array [0:(SCR1_SIZE/SCR1_NBYTES)-1];
|
||||
`elsif SCR1_TRGT_FPGA_INTEL_ARRIAV
|
||||
(* ramstyle = "M10K" *) logic [SCR1_NBYTES-1:0][7:0] memory_array [0:(SCR1_SIZE/SCR1_NBYTES)-1];
|
||||
`endif
|
||||
logic [3:0] wenbb;
|
||||
//-------------------------------------------------------------------------------
|
||||
// Port B memory behavioral description
|
||||
//-------------------------------------------------------------------------------
|
||||
assign wenbb = {4{wenb}} & webb;
|
||||
always_ff @(posedge clk) begin
|
||||
if (wenb) begin
|
||||
if (wenbb[0]) begin
|
||||
memory_array[addrb][0] <= datab[0+:8];
|
||||
end
|
||||
if (wenbb[1]) begin
|
||||
memory_array[addrb][1] <= datab[8+:8];
|
||||
end
|
||||
if (wenbb[2]) begin
|
||||
memory_array[addrb][2] <= datab[16+:8];
|
||||
end
|
||||
if (wenbb[3]) begin
|
||||
memory_array[addrb][3] <= datab[24+:8];
|
||||
end
|
||||
end
|
||||
qb <= memory_array[addrb];
|
||||
end
|
||||
//-------------------------------------------------------------------------------
|
||||
// Port A memory behavioral description
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(posedge clk) begin
|
||||
qa <= memory_array[addra];
|
||||
end
|
||||
|
||||
`else // SCR1_TRGT_FPGA_INTEL
|
||||
|
||||
// CASE: OTHERS - SCR1_TRGT_FPGA_XILINX, SIMULATION, ASIC etc
|
||||
|
||||
localparam int unsigned RAM_SIZE_WORDS = SCR1_SIZE/SCR1_NBYTES;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_TRGT_FPGA_XILINX
|
||||
(* ram_style = "block" *) logic [SCR1_WIDTH-1:0] ram_block [RAM_SIZE_WORDS-1:0];
|
||||
`else // ASIC or SIMULATION
|
||||
logic [SCR1_WIDTH-1:0] ram_block [RAM_SIZE_WORDS-1:0];
|
||||
`endif
|
||||
//-------------------------------------------------------------------------------
|
||||
// Port A memory behavioral description
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(posedge clk) begin
|
||||
if (rena) begin
|
||||
qa <= ram_block[addra];
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Port B memory behavioral description
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(posedge clk) begin
|
||||
if (wenb) begin
|
||||
for (int i=0; i<SCR1_NBYTES; i++) begin
|
||||
if (webb[i]) begin
|
||||
ram_block[addrb][i*8 +: 8] <= datab[i*8 +: 8];
|
||||
end
|
||||
end
|
||||
end
|
||||
if (renb) begin
|
||||
qb <= ram_block[addrb];
|
||||
end
|
||||
end
|
||||
|
||||
`endif // SCR1_TRGT_FPGA_INTEL
|
||||
|
||||
endmodule : scr1_dp_memory
|
||||
|
||||
`endif // SCR1_TCM_EN
|
||||
319
src_ref/top/scr1_imem_ahb.sv
Normal file
319
src_ref/top/scr1_imem_ahb.sv
Normal file
@@ -0,0 +1,319 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_imem_ahb.sv>
|
||||
/// @brief Instruction memory AHB bridge
|
||||
///
|
||||
|
||||
`include "scr1_ahb.svh"
|
||||
`include "scr1_memif.svh"
|
||||
|
||||
module scr1_imem_ahb (
|
||||
// Control Signals
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
|
||||
// Core Interface
|
||||
output logic imem_req_ack,
|
||||
input logic imem_req,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] imem_addr,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] imem_rdata,
|
||||
output type_scr1_mem_resp_e imem_resp,
|
||||
|
||||
// AHB Interface
|
||||
output logic [3:0] hprot,
|
||||
output logic [2:0] hburst,
|
||||
output logic [2:0] hsize,
|
||||
output logic [1:0] htrans,
|
||||
output logic hmastlock,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] haddr,
|
||||
input logic hready,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] hrdata,
|
||||
input logic hresp
|
||||
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local parameters declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifndef SCR1_IMEM_AHB_OUT_BP
|
||||
localparam SCR1_FIFO_WIDTH = 2;
|
||||
localparam SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
|
||||
`endif // SCR1_IMEM_AHB_OUT_BP
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local types declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
typedef enum logic {
|
||||
SCR1_FSM_ADDR = 1'b0,
|
||||
SCR1_FSM_DATA = 1'b1,
|
||||
SCR1_FSM_ERR = 1'bx
|
||||
} type_scr1_fsm_e;
|
||||
|
||||
typedef struct packed {
|
||||
logic [SCR1_AHB_WIDTH-1:0] haddr;
|
||||
} type_scr1_req_fifo_s;
|
||||
|
||||
typedef struct packed {
|
||||
logic hresp;
|
||||
logic [SCR1_AHB_WIDTH-1:0] hrdata;
|
||||
} type_scr1_resp_fifo_s;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
type_scr1_fsm_e fsm;
|
||||
logic req_fifo_rd;
|
||||
logic req_fifo_wr;
|
||||
logic req_fifo_up;
|
||||
`ifdef SCR1_IMEM_AHB_OUT_BP
|
||||
type_scr1_req_fifo_s req_fifo_r;
|
||||
type_scr1_req_fifo_s [0:0] req_fifo;
|
||||
`else // SCR1_IMEM_AHB_OUT_BP
|
||||
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo;
|
||||
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo_new;
|
||||
logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt;
|
||||
logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt_new;
|
||||
`endif // SCR1_IMEM_AHB_OUT_BP
|
||||
logic req_fifo_empty;
|
||||
logic req_fifo_full;
|
||||
|
||||
type_scr1_resp_fifo_s resp_fifo;
|
||||
logic resp_fifo_hready;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to Core
|
||||
//-------------------------------------------------------------------------------
|
||||
assign imem_req_ack = ~req_fifo_full;
|
||||
assign req_fifo_wr = ~req_fifo_full & imem_req;
|
||||
|
||||
assign imem_rdata = resp_fifo.hrdata;
|
||||
|
||||
assign imem_resp = (resp_fifo_hready)
|
||||
? (resp_fifo.hresp == SCR1_HRESP_OKAY)
|
||||
? SCR1_MEM_RESP_RDY_OK
|
||||
: SCR1_MEM_RESP_RDY_ER
|
||||
: SCR1_MEM_RESP_NOTRDY;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// REQ_FIFO
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_IMEM_AHB_OUT_BP
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_fifo_full <= 1'b0;
|
||||
end else begin
|
||||
if (~req_fifo_full) begin
|
||||
req_fifo_full <= imem_req & ~req_fifo_rd;
|
||||
end else begin
|
||||
req_fifo_full <= ~req_fifo_rd;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign req_fifo_empty = ~(req_fifo_full | imem_req);
|
||||
|
||||
assign req_fifo_up = ~req_fifo_rd & req_fifo_wr;
|
||||
always_ff @(posedge clk) begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo_r.haddr <= imem_addr;
|
||||
end
|
||||
end
|
||||
|
||||
assign req_fifo[0] = (req_fifo_full) ? req_fifo_r : imem_addr;
|
||||
|
||||
`else // SCR1_IMEM_AHB_OUT_BP
|
||||
always_comb begin
|
||||
req_fifo_up = 1'b0;
|
||||
req_fifo_cnt_new = req_fifo_cnt;
|
||||
req_fifo_new = req_fifo;
|
||||
case ({req_fifo_rd, req_fifo_wr})
|
||||
2'b00 : begin
|
||||
// nothing todo
|
||||
end
|
||||
2'b01: begin
|
||||
// FIFO write
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[req_fifo_cnt].haddr = imem_addr;
|
||||
req_fifo_cnt_new = req_fifo_cnt + 1'b1;
|
||||
end
|
||||
2'b10 : begin
|
||||
// FIFO read
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[0] = req_fifo_new[1];
|
||||
req_fifo_new[1].haddr = 'x;
|
||||
req_fifo_cnt_new = req_fifo_cnt - 1'b1;
|
||||
end
|
||||
2'b11 : begin
|
||||
// Read and Write FIFO. It is possible only when fifo_cnt = 1
|
||||
req_fifo_up = 1'b1;
|
||||
req_fifo_new[0].haddr = imem_addr;
|
||||
end
|
||||
default : begin
|
||||
req_fifo_up = 'x;
|
||||
req_fifo_cnt_new = 'x;
|
||||
req_fifo_new = 'x;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_fifo_cnt <= '0;
|
||||
end else begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo_cnt <= req_fifo_cnt_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign req_fifo_full = (req_fifo_cnt == SCR1_FIFO_WIDTH);
|
||||
assign req_fifo_empty = ~(|req_fifo_cnt);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (req_fifo_up) begin
|
||||
req_fifo <= req_fifo_new;
|
||||
end
|
||||
end
|
||||
`endif // SCR1_IMEM_AHB_OUT_BP
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FSM
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end else begin
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (hready) begin
|
||||
fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
if (hresp == SCR1_HRESP_OKAY) begin
|
||||
fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
|
||||
end else begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
fsm <= SCR1_FSM_ERR;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
req_fifo_rd = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (hready) begin
|
||||
req_fifo_rd = ~req_fifo_empty;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
req_fifo_rd = 1'bx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FIFO response
|
||||
//-------------------------------------------------------------------------------
|
||||
`ifdef SCR1_IMEM_AHB_IN_BP
|
||||
assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
|
||||
assign resp_fifo.hresp = hresp;
|
||||
assign resp_fifo.hrdata = hrdata;
|
||||
`else // SCR1_IMEM_AHB_IN_BP
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
resp_fifo_hready <= 1'b0;
|
||||
end else begin
|
||||
resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (hready & (fsm == SCR1_FSM_DATA)) begin
|
||||
resp_fifo.hresp <= hresp;
|
||||
resp_fifo.hrdata <= hrdata;
|
||||
end
|
||||
end
|
||||
`endif // SCR1_IMEM_AHB_IN_BP
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to AHB
|
||||
//-------------------------------------------------------------------------------
|
||||
assign hprot[SCR1_HPROT_DATA] = 1'b0;
|
||||
assign hprot[SCR1_HPROT_PRV] = 1'b0;
|
||||
assign hprot[SCR1_HPROT_BUF] = 1'b0;
|
||||
assign hprot[SCR1_HPROT_CACHE] = 1'b0;
|
||||
|
||||
assign hburst = SCR1_HBURST_SINGLE;
|
||||
assign hsize = SCR1_HSIZE_32B;
|
||||
assign hmastlock = 1'b0;
|
||||
|
||||
always_comb begin
|
||||
htrans = SCR1_HTRANS_IDLE;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (~req_fifo_empty) begin
|
||||
htrans = SCR1_HTRANS_NONSEQ;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (hready) begin
|
||||
if (hresp == SCR1_HRESP_OKAY) begin
|
||||
if (~req_fifo_empty) begin
|
||||
htrans = SCR1_HTRANS_NONSEQ;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
htrans = SCR1_HTRANS_ERR;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign haddr = req_fifo[0].haddr;
|
||||
|
||||
`ifdef SCR1_TRGT_SIMULATION
|
||||
//-------------------------------------------------------------------------------
|
||||
// Assertion
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Check Core interface
|
||||
SCR1_SVA_IMEM_AHB_BRIDGE_REQ_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
!$isunknown(imem_req)
|
||||
) else $error("IMEM AHB bridge Error: imem_req has unknown values");
|
||||
|
||||
SCR1_IMEM_AHB_BRIDGE_ADDR_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
imem_req |-> !$isunknown(imem_addr)
|
||||
) else $error("IMEM AHB bridge Error: imem_addr has unknown values");
|
||||
|
||||
SCR1_IMEM_AHB_BRIDGE_ADDR_ALLIGN : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
imem_req |-> (imem_addr[1:0] == '0)
|
||||
) else $error("IMEM AHB bridge Error: imem_addr has unalign values");
|
||||
|
||||
// Check AHB interface
|
||||
SCR1_IMEM_AHB_BRIDGE_HREADY_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
!$isunknown(hready)
|
||||
) else $error("IMEM AHB bridge Error: hready has unknown values");
|
||||
|
||||
SCR1_IMEM_AHB_BRIDGE_HRESP_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
!$isunknown(hresp)
|
||||
) else $error("IMEM AHB bridge Error: hresp has unknown values");
|
||||
|
||||
`endif // SCR1_TRGT_SIMULATION
|
||||
|
||||
endmodule : scr1_imem_ahb
|
||||
185
src_ref/top/scr1_imem_router.sv
Normal file
185
src_ref/top/scr1_imem_router.sv
Normal file
@@ -0,0 +1,185 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_imem_router.sv>
|
||||
/// @brief Instruction memory router
|
||||
///
|
||||
`include "scr1_memif.svh"
|
||||
`include "scr1_arch_description.svh"
|
||||
|
||||
module scr1_imem_router
|
||||
#(
|
||||
parameter SCR1_ADDR_MASK = `SCR1_IMEM_AWIDTH'hFFFF0000,
|
||||
parameter SCR1_ADDR_PATTERN = `SCR1_IMEM_AWIDTH'h00010000
|
||||
)
|
||||
(
|
||||
// Control signals
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
|
||||
// Core interface
|
||||
output logic imem_req_ack,
|
||||
input logic imem_req,
|
||||
input type_scr1_mem_cmd_e imem_cmd,
|
||||
input logic [`SCR1_IMEM_AWIDTH-1:0] imem_addr,
|
||||
output logic [`SCR1_IMEM_DWIDTH-1:0] imem_rdata,
|
||||
output type_scr1_mem_resp_e imem_resp,
|
||||
|
||||
// PORT0 interface
|
||||
input logic port0_req_ack,
|
||||
output logic port0_req,
|
||||
output type_scr1_mem_cmd_e port0_cmd,
|
||||
output logic [`SCR1_IMEM_AWIDTH-1:0] port0_addr,
|
||||
input logic [`SCR1_IMEM_DWIDTH-1:0] port0_rdata,
|
||||
input type_scr1_mem_resp_e port0_resp,
|
||||
|
||||
// PORT1 interface
|
||||
input logic port1_req_ack,
|
||||
output logic port1_req,
|
||||
output type_scr1_mem_cmd_e port1_cmd,
|
||||
output logic [`SCR1_IMEM_AWIDTH-1:0] port1_addr,
|
||||
input logic [`SCR1_IMEM_DWIDTH-1:0] port1_rdata,
|
||||
input type_scr1_mem_resp_e port1_resp
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local types declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
typedef enum logic {
|
||||
SCR1_FSM_ADDR,
|
||||
SCR1_FSM_DATA
|
||||
} type_scr1_fsm_e;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
type_scr1_fsm_e fsm;
|
||||
logic port_sel;
|
||||
logic port_sel_r;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] sel_rdata;
|
||||
type_scr1_mem_resp_e sel_resp;
|
||||
logic sel_req_ack;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// FSM
|
||||
//-------------------------------------------------------------------------------
|
||||
assign port_sel = ((imem_addr & SCR1_ADDR_MASK) == SCR1_ADDR_PATTERN);
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
port_sel_r <= 1'b0;
|
||||
end else begin
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
if (imem_req & sel_req_ack) begin
|
||||
fsm <= SCR1_FSM_DATA;
|
||||
port_sel_r <= port_sel;
|
||||
end
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
case (sel_resp)
|
||||
SCR1_MEM_RESP_RDY_OK : begin
|
||||
if (imem_req & sel_req_ack) begin
|
||||
fsm <= SCR1_FSM_DATA;
|
||||
port_sel_r <= port_sel;
|
||||
end else begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
end
|
||||
SCR1_MEM_RESP_RDY_ER : begin
|
||||
fsm <= SCR1_FSM_ADDR;
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin
|
||||
sel_req_ack = (port_sel) ? port1_req_ack : port0_req_ack;
|
||||
end else begin
|
||||
sel_req_ack = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
assign sel_rdata = (port_sel_r) ? port1_rdata : port0_rdata;
|
||||
assign sel_resp = (port_sel_r) ? port1_resp : port0_resp;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to core
|
||||
//-------------------------------------------------------------------------------
|
||||
assign imem_req_ack = sel_req_ack;
|
||||
assign imem_rdata = sel_rdata;
|
||||
assign imem_resp = sel_resp;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to PORT0
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port0_req = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
port0_req = imem_req & ~port_sel;
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
|
||||
port0_req = imem_req & ~port_sel;
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef SCR1_XPROP_EN
|
||||
assign port0_cmd = (~port_sel) ? imem_cmd : SCR1_MEM_CMD_ERROR;
|
||||
assign port0_addr = (~port_sel) ? imem_addr : 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
assign port0_cmd = imem_cmd ;
|
||||
assign port0_addr = imem_addr;
|
||||
`endif // SCR1_XPROP_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interface to PORT1
|
||||
//-------------------------------------------------------------------------------
|
||||
always_comb begin
|
||||
port1_req = 1'b0;
|
||||
case (fsm)
|
||||
SCR1_FSM_ADDR : begin
|
||||
port1_req = imem_req & port_sel;
|
||||
end
|
||||
SCR1_FSM_DATA : begin
|
||||
if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
|
||||
port1_req = imem_req & port_sel;
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef SCR1_XPROP_EN
|
||||
assign port1_cmd = (port_sel) ? imem_cmd : SCR1_MEM_CMD_ERROR;
|
||||
assign port1_addr = (port_sel) ? imem_addr : 'x;
|
||||
`else // SCR1_XPROP_EN
|
||||
assign port1_cmd = imem_cmd ;
|
||||
assign port1_addr = imem_addr;
|
||||
`endif // SCR1_XPROP_EN
|
||||
|
||||
`ifdef SCR1_TRGT_SIMULATION
|
||||
//-------------------------------------------------------------------------------
|
||||
// Assertion
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
SCR1_SVA_IMEM_RT_XCHECK : assert property (
|
||||
@(negedge clk) disable iff (~rst_n)
|
||||
imem_req |-> !$isunknown({port_sel, imem_cmd})
|
||||
) else $error("IMEM router Error: unknown values");
|
||||
|
||||
`endif // SCR1_TRGT_SIMULATION
|
||||
|
||||
endmodule : scr1_imem_router
|
||||
363
src_ref/top/scr1_mem_axi.sv
Normal file
363
src_ref/top/scr1_mem_axi.sv
Normal file
@@ -0,0 +1,363 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
||||
/// @file <scr1_mem_axi.sv>
|
||||
/// @brief Memory AXI bridge
|
||||
///
|
||||
|
||||
`include "scr1_memif.svh"
|
||||
`include "scr1_arch_description.svh"
|
||||
|
||||
module scr1_mem_axi
|
||||
#(
|
||||
parameter SCR1_REQ_BUF_SIZE = 2, // Power of 2 value
|
||||
parameter SCR1_AXI_IDWIDTH = 4,
|
||||
parameter SCR1_ADDR_WIDTH = 32,
|
||||
parameter SCR1_AXI_REQ_BP = 1,
|
||||
parameter SCR1_AXI_RESP_BP = 1
|
||||
)
|
||||
(
|
||||
// Clock and Reset
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic axi_reinit,
|
||||
// Core Interface
|
||||
output logic core_idle,
|
||||
output logic core_req_ack,
|
||||
input logic core_req,
|
||||
input type_scr1_mem_cmd_e core_cmd,
|
||||
input type_scr1_mem_width_e core_width,
|
||||
input logic [SCR1_ADDR_WIDTH-1:0] core_addr,
|
||||
input logic [31:0] core_wdata,
|
||||
output logic [31:0] core_rdata,
|
||||
output type_scr1_mem_resp_e core_resp,
|
||||
|
||||
// AXI
|
||||
output logic [SCR1_AXI_IDWIDTH-1:0] awid,
|
||||
output logic [SCR1_ADDR_WIDTH-1:0] awaddr,
|
||||
output logic [ 7:0] awlen,
|
||||
output logic [ 2:0] awsize,
|
||||
output logic [ 1:0] awburst,
|
||||
output logic awlock,
|
||||
output logic [ 3:0] awcache,
|
||||
output logic [ 2:0] awprot,
|
||||
output logic [ 3:0] awregion,
|
||||
output logic [ 3:0] awuser,
|
||||
output logic [ 3:0] awqos,
|
||||
output logic awvalid,
|
||||
input logic awready,
|
||||
output logic [31:0] wdata,
|
||||
output logic [3:0] wstrb,
|
||||
output logic wlast,
|
||||
output logic [3:0] wuser,
|
||||
output logic wvalid,
|
||||
input logic wready,
|
||||
input logic [SCR1_AXI_IDWIDTH-1:0] bid,
|
||||
input logic [ 1:0] bresp,
|
||||
input logic bvalid,
|
||||
input logic [ 3:0] buser,
|
||||
output logic bready,
|
||||
output logic [SCR1_AXI_IDWIDTH-1:0] arid,
|
||||
output logic [SCR1_ADDR_WIDTH-1:0] araddr,
|
||||
output logic [ 7:0] arlen,
|
||||
output logic [ 2:0] arsize,
|
||||
output logic [ 1:0] arburst,
|
||||
output logic arlock,
|
||||
output logic [ 3:0] arcache,
|
||||
output logic [ 2:0] arprot,
|
||||
output logic [ 3:0] arregion,
|
||||
output logic [ 3:0] aruser,
|
||||
output logic [ 3:0] arqos,
|
||||
output logic arvalid,
|
||||
input logic arready,
|
||||
input logic [SCR1_AXI_IDWIDTH-1:0] rid,
|
||||
input logic [31:0] rdata,
|
||||
input logic [ 1:0] rresp,
|
||||
input logic rlast,
|
||||
input logic [ 3:0] ruser,
|
||||
input logic rvalid,
|
||||
output logic rready
|
||||
);
|
||||
|
||||
|
||||
// Local functions
|
||||
function automatic logic [2:0] width2axsize (
|
||||
input type_scr1_mem_width_e width );
|
||||
logic [2:0] axsize;
|
||||
begin
|
||||
case (width)
|
||||
SCR1_MEM_WIDTH_BYTE : axsize = 3'b000;
|
||||
SCR1_MEM_WIDTH_HWORD: axsize = 3'b001;
|
||||
SCR1_MEM_WIDTH_WORD : axsize = 3'b010;
|
||||
default: axsize = 'x;
|
||||
endcase
|
||||
|
||||
return axsize;
|
||||
end
|
||||
endfunction: width2axsize
|
||||
|
||||
typedef struct packed {
|
||||
type_scr1_mem_width_e axi_width;
|
||||
logic [SCR1_ADDR_WIDTH-1:0] axi_addr;
|
||||
logic [31:0] axi_wdata;
|
||||
} type_scr1_request_s;
|
||||
|
||||
typedef struct packed {
|
||||
logic req_write;
|
||||
logic req_addr;
|
||||
logic req_data;
|
||||
logic req_resp;
|
||||
} type_scr1_req_status_s;
|
||||
|
||||
|
||||
type_scr1_request_s [SCR1_REQ_BUF_SIZE-1:0] req_fifo;
|
||||
type_scr1_req_status_s [SCR1_REQ_BUF_SIZE-1:0] req_status;
|
||||
type_scr1_req_status_s [SCR1_REQ_BUF_SIZE-1:0] req_status_new;
|
||||
logic [SCR1_REQ_BUF_SIZE-1:0] req_status_en;
|
||||
logic [$clog2(SCR1_REQ_BUF_SIZE)-1:0] req_aval_ptr;
|
||||
logic [$clog2(SCR1_REQ_BUF_SIZE)-1:0] req_proc_ptr;
|
||||
logic [$clog2(SCR1_REQ_BUF_SIZE)-1:0] req_done_ptr;
|
||||
logic rresp_err;
|
||||
logic [31:0] rcvd_rdata;
|
||||
type_scr1_mem_resp_e rcvd_resp;
|
||||
logic force_read;
|
||||
logic force_write;
|
||||
|
||||
|
||||
|
||||
assign core_req_ack = ~axi_reinit &
|
||||
~req_status[req_aval_ptr].req_resp &
|
||||
core_resp!=SCR1_MEM_RESP_RDY_ER;
|
||||
|
||||
|
||||
assign rready = ~req_status[req_done_ptr].req_write;
|
||||
assign bready = req_status[req_done_ptr].req_write;
|
||||
|
||||
|
||||
assign force_read = bit'(SCR1_AXI_REQ_BP) & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_RD;
|
||||
assign force_write = bit'(SCR1_AXI_REQ_BP) & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_WR;
|
||||
|
||||
|
||||
always_comb begin: idle_status
|
||||
core_idle = 1'b1;
|
||||
for (int unsigned i=0; i<SCR1_REQ_BUF_SIZE; ++i) begin
|
||||
core_idle &= req_status[i].req_resp==1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (core_req & core_req_ack) begin
|
||||
req_fifo[req_aval_ptr].axi_width <= core_width;
|
||||
req_fifo[req_aval_ptr].axi_addr <= core_addr;
|
||||
req_fifo[req_aval_ptr].axi_wdata <= core_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
// Request Status Queue
|
||||
// It is used for holding control info of processing requests
|
||||
|
||||
// Combinational logic of Request Status Queue
|
||||
always_comb begin
|
||||
// Default
|
||||
req_status_en = '0; // No update
|
||||
req_status_new = req_status; // Hold request info
|
||||
|
||||
// Update status on new core request
|
||||
if( core_req & core_req_ack ) begin
|
||||
req_status_en[req_aval_ptr] = 1'd1;
|
||||
|
||||
req_status_new[req_aval_ptr].req_resp = 1'd1;
|
||||
req_status_new[req_aval_ptr].req_write = core_cmd == SCR1_MEM_CMD_WR;
|
||||
|
||||
req_status_new[req_aval_ptr].req_addr = ~( (force_read & arready) |
|
||||
(force_write & awready) );
|
||||
|
||||
req_status_new[req_aval_ptr].req_data = ~( (force_write & wready & awlen == 8'd0) |
|
||||
(~force_write & core_cmd == SCR1_MEM_CMD_RD) );
|
||||
end
|
||||
|
||||
// Update status on AXI address phase
|
||||
if ( (awvalid & awready) | (arvalid & arready) ) begin
|
||||
req_status_en[req_proc_ptr] = 1'd1;
|
||||
req_status_new[req_proc_ptr].req_addr = 1'd0;
|
||||
end
|
||||
|
||||
// Update status on AXI data phase
|
||||
if ( wvalid & wready & wlast ) begin
|
||||
req_status_en[req_proc_ptr] = 1'd1;
|
||||
req_status_new[req_proc_ptr].req_data = 1'd0;
|
||||
end
|
||||
|
||||
// Update status when AXI finish transaction
|
||||
if ( (bvalid & bready) | (rvalid & rready & rlast) ) begin
|
||||
req_status_en[req_done_ptr] = 1'd1;
|
||||
req_status_new[req_done_ptr].req_resp = 1'd0;
|
||||
end
|
||||
end
|
||||
|
||||
// Request Status Queue register
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_status <= '0;
|
||||
end else begin
|
||||
for (int unsigned i = 0; i < SCR1_REQ_BUF_SIZE; ++i) begin
|
||||
if ( req_status_en[i] ) begin
|
||||
req_status[i] <= req_status_new[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) req_aval_ptr <= '0;
|
||||
else if (core_req & core_req_ack) req_aval_ptr <= req_aval_ptr + 1'b1;
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_proc_ptr <= '0;
|
||||
end else begin
|
||||
if (( awvalid & awready & wvalid & wready & wlast) |
|
||||
(~force_write & ~req_status[req_proc_ptr].req_data & awvalid & awready ) |
|
||||
(~force_write & ~req_status[req_proc_ptr].req_addr & wvalid & wready & wlast) |
|
||||
( ~req_status[req_proc_ptr].req_data & arvalid & arready ) ) begin
|
||||
|
||||
req_proc_ptr <= req_proc_ptr + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
req_done_ptr <= '0;
|
||||
end else begin
|
||||
if ((bvalid & bready | rvalid & rready & rlast) & req_status[req_done_ptr].req_resp) begin
|
||||
|
||||
req_done_ptr <= req_done_ptr + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
assign arvalid = req_status[req_proc_ptr].req_addr & ~req_status[req_proc_ptr].req_write | force_read;
|
||||
assign awvalid = req_status[req_proc_ptr].req_addr & req_status[req_proc_ptr].req_write | force_write;
|
||||
assign wvalid = req_status[req_proc_ptr].req_data & req_status[req_proc_ptr].req_write | force_write;
|
||||
|
||||
assign araddr = (~force_read )? req_fifo[req_proc_ptr].axi_addr : core_addr;
|
||||
assign awaddr = (~force_write)? req_fifo[req_proc_ptr].axi_addr : core_addr;
|
||||
|
||||
always_comb begin
|
||||
if (bvalid & bready & req_status[req_done_ptr].req_resp) begin
|
||||
rcvd_resp = (bresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
|
||||
SCR1_MEM_RESP_RDY_ER;
|
||||
end else begin
|
||||
if (rvalid & rready & rlast & req_status[req_done_ptr].req_resp) begin
|
||||
rcvd_resp = (rresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
|
||||
SCR1_MEM_RESP_RDY_ER;
|
||||
end else begin
|
||||
rcvd_resp = SCR1_MEM_RESP_NOTRDY;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
// Write data signals adaptation
|
||||
always_comb begin
|
||||
if (force_write)
|
||||
case (core_width)
|
||||
SCR1_MEM_WIDTH_BYTE : wstrb = 4'h1 << core_addr[1:0];
|
||||
SCR1_MEM_WIDTH_HWORD: wstrb = 4'h3 << core_addr[1:0];
|
||||
SCR1_MEM_WIDTH_WORD : wstrb = 4'hf << core_addr[1:0];
|
||||
default: wstrb = 'x;
|
||||
endcase
|
||||
else
|
||||
case (req_fifo[req_proc_ptr].axi_width)
|
||||
SCR1_MEM_WIDTH_BYTE : wstrb = 4'h1 << req_fifo[req_proc_ptr].axi_addr[1:0];
|
||||
SCR1_MEM_WIDTH_HWORD: wstrb = 4'h3 << req_fifo[req_proc_ptr].axi_addr[1:0];
|
||||
SCR1_MEM_WIDTH_WORD : wstrb = 4'hf << req_fifo[req_proc_ptr].axi_addr[1:0];
|
||||
default: wstrb = 'x;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
assign wdata = (force_write)? core_wdata << (8* core_addr[1:0]) :
|
||||
req_fifo[req_proc_ptr].axi_wdata << (8* req_fifo[req_proc_ptr].axi_addr[1:0]);
|
||||
|
||||
|
||||
// Read data adaptation
|
||||
always_comb begin
|
||||
case (req_fifo[req_done_ptr].axi_width)
|
||||
SCR1_MEM_WIDTH_BYTE : rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
|
||||
SCR1_MEM_WIDTH_HWORD: rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
|
||||
SCR1_MEM_WIDTH_WORD : rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
|
||||
default: rcvd_rdata = 'x;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
generate
|
||||
if (SCR1_AXI_RESP_BP == 1) begin : axi_resp_bp
|
||||
assign core_rdata = (rvalid & rready & rlast) ? rcvd_rdata : '0;
|
||||
assign core_resp = (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
|
||||
end else begin : axi_resp_no_bp
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) core_resp <= SCR1_MEM_RESP_NOTRDY;
|
||||
else core_resp <= (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if (rvalid & rready & rlast) core_rdata <= rcvd_rdata;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
// AXI interface assignments
|
||||
assign awid = SCR1_AXI_IDWIDTH'(1);
|
||||
assign awlen = 8'd0;
|
||||
assign awsize = (force_write) ? width2axsize(core_width) : width2axsize(req_fifo[req_proc_ptr].axi_width);
|
||||
assign awburst = 2'd1;
|
||||
assign awcache = 4'd2;
|
||||
assign awlock = '0;
|
||||
assign awprot = '0;
|
||||
assign awregion = '0;
|
||||
assign awuser = '0;
|
||||
assign awqos = '0;
|
||||
|
||||
assign arid = SCR1_AXI_IDWIDTH'(0);
|
||||
assign arlen = 8'd0;
|
||||
assign arsize = (force_read) ? width2axsize(core_width) : width2axsize(req_fifo[req_proc_ptr].axi_width);
|
||||
assign arburst = 2'd1;
|
||||
assign arcache = 4'd2;
|
||||
assign arprot = '0;
|
||||
assign arregion = '0;
|
||||
assign arlock = '0;
|
||||
assign arqos = '0;
|
||||
assign aruser = '0;
|
||||
|
||||
assign wlast = 1'd1;
|
||||
assign wuser = '0;
|
||||
|
||||
|
||||
`ifdef SCR1_TRGT_SIMULATION
|
||||
//-------------------------------------------------------------------------------
|
||||
// Assertion
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// X checks
|
||||
SCR1_SVA_AXI_X_CHECK0 : assert property (@(negedge clk) disable iff (~rst_n) !$isunknown({core_req, awready, wready, bvalid, arready, rvalid}) )
|
||||
else $error("AXI bridge: X state on input");
|
||||
SCR1_SVA_AXI_X_CHECK1 : assert property (@(negedge clk) disable iff (~rst_n) core_req |->
|
||||
!$isunknown({core_cmd, core_width, core_addr}) )
|
||||
else $error("AXI bridge: X state on input");
|
||||
SCR1_SVA_AXI_X_CHECK2 : assert property (@(negedge clk) disable iff (~rst_n) bvalid |->
|
||||
!$isunknown({bid, bresp}) )
|
||||
else $error("AXI bridge: X state on input");
|
||||
SCR1_SVA_AXI_X_CHECK3 : assert property (@(negedge clk) disable iff (~rst_n) rvalid |->
|
||||
!$isunknown({rid, rresp}) )
|
||||
else $error("AXI bridge: X state on input");
|
||||
`endif // SCR1_TRGT_SIMULATION
|
||||
|
||||
endmodule : scr1_mem_axi
|
||||
131
src_ref/top/scr1_tcm.sv
Normal file
131
src_ref/top/scr1_tcm.sv
Normal file
@@ -0,0 +1,131 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
||||
/// @file <scr1_tcm.sv>
|
||||
/// @brief Tightly-Coupled Memory (TCM)
|
||||
///
|
||||
|
||||
`include "scr1_memif.svh"
|
||||
`include "scr1_arch_description.svh"
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
module scr1_tcm
|
||||
#(
|
||||
parameter SCR1_TCM_SIZE = `SCR1_IMEM_AWIDTH'h00010000
|
||||
)
|
||||
(
|
||||
// Control signals
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
// Core instruction interface
|
||||
output logic imem_req_ack,
|
||||
input logic imem_req,
|
||||
input logic [`SCR1_IMEM_AWIDTH-1:0] imem_addr,
|
||||
output logic [`SCR1_IMEM_DWIDTH-1:0] imem_rdata,
|
||||
output type_scr1_mem_resp_e imem_resp,
|
||||
|
||||
// Core data interface
|
||||
output logic dmem_req_ack,
|
||||
input logic dmem_req,
|
||||
input type_scr1_mem_cmd_e dmem_cmd,
|
||||
input type_scr1_mem_width_e dmem_width,
|
||||
input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata,
|
||||
output type_scr1_mem_resp_e dmem_resp
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
logic imem_req_en;
|
||||
logic dmem_req_en;
|
||||
logic imem_rd;
|
||||
logic dmem_rd;
|
||||
logic dmem_wr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] dmem_writedata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata_local;
|
||||
logic [3:0] dmem_byteen;
|
||||
logic [1:0] dmem_rdata_shift_reg;
|
||||
//-------------------------------------------------------------------------------
|
||||
// Core interface
|
||||
//-------------------------------------------------------------------------------
|
||||
assign imem_req_en = (imem_resp == SCR1_MEM_RESP_RDY_OK) ^ imem_req;
|
||||
assign dmem_req_en = (dmem_resp == SCR1_MEM_RESP_RDY_OK) ^ dmem_req;
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
imem_resp <= SCR1_MEM_RESP_NOTRDY;
|
||||
end else if (imem_req_en) begin
|
||||
imem_resp <= imem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
dmem_resp <= SCR1_MEM_RESP_NOTRDY;
|
||||
end else if (dmem_req_en) begin
|
||||
dmem_resp <= dmem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
|
||||
end
|
||||
end
|
||||
|
||||
assign imem_req_ack = 1'b1;
|
||||
assign dmem_req_ack = 1'b1;
|
||||
//-------------------------------------------------------------------------------
|
||||
// Memory data composing
|
||||
//-------------------------------------------------------------------------------
|
||||
assign imem_rd = imem_req;
|
||||
assign dmem_rd = dmem_req & (dmem_cmd == SCR1_MEM_CMD_RD);
|
||||
assign dmem_wr = dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR);
|
||||
|
||||
always_comb begin
|
||||
dmem_writedata = dmem_wdata;
|
||||
dmem_byteen = 4'b1111;
|
||||
case ( dmem_width )
|
||||
SCR1_MEM_WIDTH_BYTE : begin
|
||||
dmem_writedata = {(`SCR1_DMEM_DWIDTH / 8){dmem_wdata[7:0]}};
|
||||
dmem_byteen = 4'b0001 << dmem_addr[1:0];
|
||||
end
|
||||
SCR1_MEM_WIDTH_HWORD : begin
|
||||
dmem_writedata = {(`SCR1_DMEM_DWIDTH / 16){dmem_wdata[15:0]}};
|
||||
dmem_byteen = 4'b0011 << {dmem_addr[1], 1'b0};
|
||||
end
|
||||
default : begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
//-------------------------------------------------------------------------------
|
||||
// Memory instantiation
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_dp_memory #(
|
||||
.SCR1_WIDTH ( 32 ),
|
||||
.SCR1_SIZE ( SCR1_TCM_SIZE )
|
||||
) i_dp_memory (
|
||||
.clk ( clk ),
|
||||
// Instruction port
|
||||
// Port A
|
||||
.rena ( imem_rd ),
|
||||
.addra ( imem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ),
|
||||
.qa ( imem_rdata ),
|
||||
// Data port
|
||||
// Port B
|
||||
.renb ( dmem_rd ),
|
||||
.wenb ( dmem_wr ),
|
||||
.webb ( dmem_byteen ),
|
||||
.addrb ( dmem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ),
|
||||
.qb ( dmem_rdata_local ),
|
||||
.datab ( dmem_writedata )
|
||||
);
|
||||
//-------------------------------------------------------------------------------
|
||||
// Data memory output generation
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(posedge clk) begin
|
||||
if (dmem_rd) begin
|
||||
dmem_rdata_shift_reg <= dmem_addr[1:0];
|
||||
end
|
||||
end
|
||||
|
||||
assign dmem_rdata = dmem_rdata_local >> ( 8 * dmem_rdata_shift_reg );
|
||||
|
||||
endmodule : scr1_tcm
|
||||
|
||||
`endif // SCR1_TCM_EN
|
||||
271
src_ref/top/scr1_timer.sv
Normal file
271
src_ref/top/scr1_timer.sv
Normal file
@@ -0,0 +1,271 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_timer.sv>
|
||||
/// @brief Memory-mapped Timer
|
||||
///
|
||||
|
||||
`include "scr1_arch_description.svh"
|
||||
`include "scr1_memif.svh"
|
||||
|
||||
module scr1_timer (
|
||||
// Common
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
input logic rtc_clk,
|
||||
|
||||
// Memory interface
|
||||
input logic dmem_req,
|
||||
input type_scr1_mem_cmd_e dmem_cmd,
|
||||
input type_scr1_mem_width_e dmem_width,
|
||||
input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr,
|
||||
input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata,
|
||||
output logic dmem_req_ack,
|
||||
output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata,
|
||||
output type_scr1_mem_resp_e dmem_resp,
|
||||
|
||||
// Timer interface
|
||||
output logic [63:0] timer_val,
|
||||
output logic timer_irq
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local parameters declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
localparam int unsigned SCR1_TIMER_ADDR_WIDTH = 5;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_CONTROL = 5'h0;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_DIVIDER = 5'h4;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMELO = 5'h8;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMEHI = 5'hC;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMECMPLO = 5'h10;
|
||||
localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMECMPHI = 5'h14;
|
||||
|
||||
localparam int unsigned SCR1_TIMER_CONTROL_EN_OFFSET = 0;
|
||||
localparam int unsigned SCR1_TIMER_CONTROL_CLKSRC_OFFSET = 1;
|
||||
localparam int unsigned SCR1_TIMER_DIVIDER_WIDTH = 10;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signals declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
logic [63:0] mtime_reg;
|
||||
logic [63:0] mtime_new;
|
||||
logic [63:0] mtimecmp_reg;
|
||||
logic [63:0] mtimecmp_new;
|
||||
logic timer_en;
|
||||
logic timer_clksrc_rtc;
|
||||
logic [SCR1_TIMER_DIVIDER_WIDTH-1:0] timer_div;
|
||||
|
||||
logic control_up;
|
||||
logic divider_up;
|
||||
logic mtimelo_up;
|
||||
logic mtimehi_up;
|
||||
logic mtimecmplo_up;
|
||||
logic mtimecmphi_up;
|
||||
|
||||
logic dmem_req_valid;
|
||||
|
||||
logic [3:0] rtc_sync;
|
||||
logic rtc_ext_pulse;
|
||||
logic [SCR1_TIMER_DIVIDER_WIDTH-1:0] timeclk_cnt;
|
||||
logic timeclk_cnt_en;
|
||||
logic time_posedge;
|
||||
logic time_cmp_flag;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Registers
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// CONTROL
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
timer_en <= 1'b1;
|
||||
timer_clksrc_rtc <= 1'b0;
|
||||
end else begin
|
||||
if (control_up) begin
|
||||
timer_en <= dmem_wdata[SCR1_TIMER_CONTROL_EN_OFFSET];
|
||||
timer_clksrc_rtc <= dmem_wdata[SCR1_TIMER_CONTROL_CLKSRC_OFFSET];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// DIVIDER
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
timer_div <= '0;
|
||||
end else begin
|
||||
if (divider_up) begin
|
||||
timer_div <= dmem_wdata[SCR1_TIMER_DIVIDER_WIDTH-1:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// MTIME
|
||||
assign time_posedge = (timeclk_cnt_en & (timeclk_cnt == 0));
|
||||
|
||||
always_comb begin
|
||||
mtime_new = mtime_reg;
|
||||
if (time_posedge) begin
|
||||
mtime_new = mtime_reg + 1'b1;
|
||||
end
|
||||
if (mtimelo_up) begin
|
||||
mtime_new[31:0] = dmem_wdata;
|
||||
end
|
||||
if (mtimehi_up) begin
|
||||
mtime_new[63:32] = dmem_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
mtime_reg <= '0;
|
||||
end else begin
|
||||
if (time_posedge | mtimelo_up | mtimehi_up) begin
|
||||
mtime_reg <= mtime_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// MTIMECMP
|
||||
always_comb begin
|
||||
mtimecmp_new = mtimecmp_reg;
|
||||
if (mtimecmplo_up) begin
|
||||
mtimecmp_new[31:0] = dmem_wdata;
|
||||
end
|
||||
if (mtimecmphi_up) begin
|
||||
mtimecmp_new[63:32] = dmem_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
mtimecmp_reg <= '0;
|
||||
end else begin
|
||||
if (mtimecmplo_up | mtimecmphi_up) begin
|
||||
mtimecmp_reg <= mtimecmp_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Interrupt pending
|
||||
//-------------------------------------------------------------------------------
|
||||
assign time_cmp_flag = (mtime_reg >= ((mtimecmplo_up | mtimecmphi_up) ? mtimecmp_new : mtimecmp_reg));
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
timer_irq <= 1'b0;
|
||||
end else begin
|
||||
if (~timer_irq) begin
|
||||
timer_irq <= time_cmp_flag;
|
||||
end else begin // 1'b1
|
||||
if (mtimecmplo_up | mtimecmphi_up) begin
|
||||
timer_irq <= time_cmp_flag;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Timer divider
|
||||
//-------------------------------------------------------------------------------
|
||||
assign timeclk_cnt_en = (~timer_clksrc_rtc ? 1'b1 : rtc_ext_pulse) & timer_en;
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
timeclk_cnt <= '0;
|
||||
end else begin
|
||||
case (1'b1)
|
||||
divider_up : timeclk_cnt <= dmem_wdata[SCR1_TIMER_DIVIDER_WIDTH-1:0];
|
||||
time_posedge : timeclk_cnt <= timer_div;
|
||||
timeclk_cnt_en : timeclk_cnt <= timeclk_cnt - 1'b1;
|
||||
default : begin end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// RTC synchronization
|
||||
//-------------------------------------------------------------------------------
|
||||
assign rtc_ext_pulse = rtc_sync[3] ^ rtc_sync[2];
|
||||
|
||||
always_ff @(negedge rst_n, posedge rtc_clk) begin
|
||||
if (~rst_n) begin
|
||||
rtc_sync[0] <= 1'b0;
|
||||
end else begin
|
||||
if (timer_clksrc_rtc) begin
|
||||
rtc_sync[0] <= ~rtc_sync[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
rtc_sync[3:1] <= '0;
|
||||
end else begin
|
||||
if (timer_clksrc_rtc) begin
|
||||
rtc_sync[3:1] <= rtc_sync[2:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Memory interface
|
||||
//-------------------------------------------------------------------------------
|
||||
assign dmem_req_valid = (dmem_width == SCR1_MEM_WIDTH_WORD) & (~|dmem_addr[1:0]) &
|
||||
(dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:2] <= SCR1_TIMER_MTIMECMPHI[SCR1_TIMER_ADDR_WIDTH-1:2]);
|
||||
|
||||
assign dmem_req_ack = 1'b1;
|
||||
|
||||
always_ff @(negedge rst_n, posedge clk) begin
|
||||
if (~rst_n) begin
|
||||
dmem_resp <= SCR1_MEM_RESP_NOTRDY;
|
||||
dmem_rdata <= '0;
|
||||
end else begin
|
||||
if (dmem_req) begin
|
||||
if (dmem_req_valid) begin
|
||||
dmem_resp <= SCR1_MEM_RESP_RDY_OK;
|
||||
if (dmem_cmd == SCR1_MEM_CMD_RD) begin
|
||||
case (dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:0])
|
||||
SCR1_TIMER_CONTROL : dmem_rdata <= `SCR1_DMEM_DWIDTH'({timer_clksrc_rtc, timer_en});
|
||||
SCR1_TIMER_DIVIDER : dmem_rdata <= `SCR1_DMEM_DWIDTH'(timer_div);
|
||||
SCR1_TIMER_MTIMELO : dmem_rdata <= mtime_reg[31:0];
|
||||
SCR1_TIMER_MTIMEHI : dmem_rdata <= mtime_reg[63:32];
|
||||
SCR1_TIMER_MTIMECMPLO : dmem_rdata <= mtimecmp_reg[31:0];
|
||||
SCR1_TIMER_MTIMECMPHI : dmem_rdata <= mtimecmp_reg[63:32];
|
||||
default : begin end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
dmem_resp <= SCR1_MEM_RESP_RDY_ER;
|
||||
end
|
||||
end else begin
|
||||
dmem_resp <= SCR1_MEM_RESP_NOTRDY;
|
||||
dmem_rdata <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
control_up = 1'b0;
|
||||
divider_up = 1'b0;
|
||||
mtimelo_up = 1'b0;
|
||||
mtimehi_up = 1'b0;
|
||||
mtimecmplo_up = 1'b0;
|
||||
mtimecmphi_up = 1'b0;
|
||||
if (dmem_req & dmem_req_valid & (dmem_cmd == SCR1_MEM_CMD_WR)) begin
|
||||
case (dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:0])
|
||||
SCR1_TIMER_CONTROL : control_up = 1'b1;
|
||||
SCR1_TIMER_DIVIDER : divider_up = 1'b1;
|
||||
SCR1_TIMER_MTIMELO : mtimelo_up = 1'b1;
|
||||
SCR1_TIMER_MTIMEHI : mtimehi_up = 1'b1;
|
||||
SCR1_TIMER_MTIMECMPLO : mtimecmplo_up = 1'b1;
|
||||
SCR1_TIMER_MTIMECMPHI : mtimecmphi_up = 1'b1;
|
||||
default : begin end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Timer interface
|
||||
//-------------------------------------------------------------------------------
|
||||
assign timer_val = mtime_reg;
|
||||
|
||||
endmodule : scr1_timer
|
||||
513
src_ref/top/scr1_top_ahb.sv
Normal file
513
src_ref/top/scr1_top_ahb.sv
Normal file
@@ -0,0 +1,513 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
|
||||
/// @file <scr1_top_ahb.sv>
|
||||
/// @brief SCR1 AHB top
|
||||
///
|
||||
|
||||
`include "scr1_arch_description.svh"
|
||||
`include "scr1_memif.svh"
|
||||
`include "scr1_ahb.svh"
|
||||
`ifdef SCR1_IPIC_EN
|
||||
`include "scr1_ipic.svh"
|
||||
`endif // SCR1_IPIC_EN
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
`define SCR1_IMEM_ROUTER_EN
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
module scr1_top_ahb (
|
||||
// Control
|
||||
input logic pwrup_rst_n, // Power-Up Reset
|
||||
input logic rst_n, // Regular Reset signal
|
||||
input logic cpu_rst_n, // CPU Reset (Core Reset)
|
||||
input logic test_mode, // Test mode
|
||||
input logic test_rst_n, // Test mode's reset
|
||||
input logic clk, // System clock
|
||||
input logic rtc_clk, // Real-time clock
|
||||
`ifdef SCR1_DBG_EN
|
||||
output logic sys_rst_n_o, // External System Reset output
|
||||
// (for the processor cluster's components or
|
||||
// external SOC (could be useful in small
|
||||
// SCR-core-centric SOCs))
|
||||
output logic sys_rdc_qlfy_o, // System-to-External SOC Reset Domain Crossing Qualifier
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Fuses
|
||||
input logic [`SCR1_XLEN-1:0] fuse_mhartid, // Hart ID
|
||||
`ifdef SCR1_DBG_EN
|
||||
input logic [31:0] fuse_idcode, // TAPC IDCODE
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// IRQ
|
||||
`ifdef SCR1_IPIC_EN
|
||||
input logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines, // IRQ lines to IPIC
|
||||
`else // SCR1_IPIC_EN
|
||||
input logic ext_irq, // External IRQ input
|
||||
`endif // SCR1_IPIC_EN
|
||||
input logic soft_irq, // Software IRQ input
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// -- JTAG I/F
|
||||
input logic trst_n,
|
||||
input logic tck,
|
||||
input logic tms,
|
||||
input logic tdi,
|
||||
output logic tdo,
|
||||
output logic tdo_en,
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction Memory Interface
|
||||
output logic [3:0] imem_hprot,
|
||||
output logic [2:0] imem_hburst,
|
||||
output logic [2:0] imem_hsize,
|
||||
output logic [1:0] imem_htrans,
|
||||
output logic imem_hmastlock,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] imem_haddr,
|
||||
input logic imem_hready,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] imem_hrdata,
|
||||
input logic imem_hresp,
|
||||
|
||||
// Data Memory Interface
|
||||
output logic [3:0] dmem_hprot,
|
||||
output logic [2:0] dmem_hburst,
|
||||
output logic [2:0] dmem_hsize,
|
||||
output logic [1:0] dmem_htrans,
|
||||
output logic dmem_hmastlock,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] dmem_haddr,
|
||||
output logic dmem_hwrite,
|
||||
output logic [SCR1_AHB_WIDTH-1:0] dmem_hwdata,
|
||||
input logic dmem_hready,
|
||||
input logic [SCR1_AHB_WIDTH-1:0] dmem_hrdata,
|
||||
input logic dmem_hresp
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local parameters
|
||||
//-------------------------------------------------------------------------------
|
||||
localparam int unsigned SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM = 2;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
// Reset logic
|
||||
logic pwrup_rst_n_sync;
|
||||
logic rst_n_sync;
|
||||
logic cpu_rst_n_sync;
|
||||
logic core_rst_n_local;
|
||||
`ifdef SCR1_DBG_EN
|
||||
logic tapc_trst_n;
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction memory interface from core to router
|
||||
logic core_imem_req_ack;
|
||||
logic core_imem_req;
|
||||
type_scr1_mem_cmd_e core_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] core_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] core_imem_rdata;
|
||||
type_scr1_mem_resp_e core_imem_resp;
|
||||
|
||||
// Data memory interface from core to router
|
||||
logic core_dmem_req_ack;
|
||||
logic core_dmem_req;
|
||||
type_scr1_mem_cmd_e core_dmem_cmd;
|
||||
type_scr1_mem_width_e core_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] core_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] core_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] core_dmem_rdata;
|
||||
type_scr1_mem_resp_e core_dmem_resp;
|
||||
|
||||
// Instruction memory interface from router to AHB bridge
|
||||
logic ahb_imem_req_ack;
|
||||
logic ahb_imem_req;
|
||||
type_scr1_mem_cmd_e ahb_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] ahb_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] ahb_imem_rdata;
|
||||
type_scr1_mem_resp_e ahb_imem_resp;
|
||||
|
||||
// Data memory interface from router to AHB bridge
|
||||
logic ahb_dmem_req_ack;
|
||||
logic ahb_dmem_req;
|
||||
type_scr1_mem_cmd_e ahb_dmem_cmd;
|
||||
type_scr1_mem_width_e ahb_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] ahb_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] ahb_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] ahb_dmem_rdata;
|
||||
type_scr1_mem_resp_e ahb_dmem_resp;
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
// Instruction memory interface from router to TCM
|
||||
logic tcm_imem_req_ack;
|
||||
logic tcm_imem_req;
|
||||
type_scr1_mem_cmd_e tcm_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] tcm_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] tcm_imem_rdata;
|
||||
type_scr1_mem_resp_e tcm_imem_resp;
|
||||
|
||||
// Data memory interface from router to TCM
|
||||
logic tcm_dmem_req_ack;
|
||||
logic tcm_dmem_req;
|
||||
type_scr1_mem_cmd_e tcm_dmem_cmd;
|
||||
type_scr1_mem_width_e tcm_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] tcm_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] tcm_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] tcm_dmem_rdata;
|
||||
type_scr1_mem_resp_e tcm_dmem_resp;
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
// Data memory interface from router to memory-mapped timer
|
||||
logic timer_dmem_req_ack;
|
||||
logic timer_dmem_req;
|
||||
type_scr1_mem_cmd_e timer_dmem_cmd;
|
||||
type_scr1_mem_width_e timer_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] timer_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] timer_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] timer_dmem_rdata;
|
||||
type_scr1_mem_resp_e timer_dmem_resp;
|
||||
|
||||
logic timer_irq;
|
||||
logic [63:0] timer_val;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Reset logic
|
||||
//-------------------------------------------------------------------------------
|
||||
// Power-Up Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_pwrup_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (1'b1 ),
|
||||
.rst_n_out (pwrup_rst_n_sync)
|
||||
);
|
||||
|
||||
// Regular Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (rst_n ),
|
||||
.rst_n_out (rst_n_sync )
|
||||
);
|
||||
|
||||
// CPU Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_cpu_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (cpu_rst_n ),
|
||||
.rst_n_out (cpu_rst_n_sync )
|
||||
);
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// TAPC Reset
|
||||
scr1_reset_and2_cell i_tapc_rstn_and2_cell (
|
||||
.rst_n_in ({trst_n, pwrup_rst_n}),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_out (tapc_trst_n )
|
||||
);
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// SCR1 core instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_core_top i_core_top (
|
||||
// Common
|
||||
.pwrup_rst_n (pwrup_rst_n_sync ),
|
||||
.rst_n (rst_n_sync ),
|
||||
.cpu_rst_n (cpu_rst_n_sync ),
|
||||
.test_mode (test_mode ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.clk (clk ),
|
||||
.core_rst_n_o (core_rst_n_local ),
|
||||
.core_rdc_qlfy_o ( ),
|
||||
`ifdef SCR1_DBG_EN
|
||||
.sys_rst_n_o (sys_rst_n_o ),
|
||||
.sys_rdc_qlfy_o (sys_rdc_qlfy_o ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Fuses
|
||||
.core_fuse_mhartid_i (fuse_mhartid ),
|
||||
`ifdef SCR1_DBG_EN
|
||||
.tapc_fuse_idcode_i (fuse_idcode ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// IRQ
|
||||
`ifdef SCR1_IPIC_EN
|
||||
.core_irq_lines_i (irq_lines ),
|
||||
`else // SCR1_IPIC_EN
|
||||
.core_irq_ext_i (ext_irq ),
|
||||
`endif // SCR1_IPIC_EN
|
||||
.core_irq_soft_i (soft_irq ),
|
||||
.core_irq_mtimer_i (timer_irq ),
|
||||
|
||||
// Memory-mapped external timer
|
||||
.core_mtimer_val_i (timer_val ),
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// Debug interface
|
||||
.tapc_trst_n (tapc_trst_n ),
|
||||
.tapc_tck (tck ),
|
||||
.tapc_tms (tms ),
|
||||
.tapc_tdi (tdi ),
|
||||
.tapc_tdo (tdo ),
|
||||
.tapc_tdo_en (tdo_en ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction memory interface
|
||||
.imem2core_req_ack_i (core_imem_req_ack),
|
||||
.core2imem_req_o (core_imem_req ),
|
||||
.core2imem_cmd_o (core_imem_cmd ),
|
||||
.core2imem_addr_o (core_imem_addr ),
|
||||
.imem2core_rdata_i (core_imem_rdata ),
|
||||
.imem2core_resp_i (core_imem_resp ),
|
||||
|
||||
// Data memory interface
|
||||
.dmem2core_req_ack_i (core_dmem_req_ack),
|
||||
.core2dmem_req_o (core_dmem_req ),
|
||||
.core2dmem_cmd_o (core_dmem_cmd ),
|
||||
.core2dmem_width_o (core_dmem_width ),
|
||||
.core2dmem_addr_o (core_dmem_addr ),
|
||||
.core2dmem_wdata_o (core_dmem_wdata ),
|
||||
.dmem2core_rdata_i (core_dmem_rdata ),
|
||||
.dmem2core_resp_i (core_dmem_resp )
|
||||
);
|
||||
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
//-------------------------------------------------------------------------------
|
||||
// TCM instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_tcm #(
|
||||
.SCR1_TCM_SIZE (`SCR1_DMEM_AWIDTH'(~SCR1_TCM_ADDR_MASK + 1'b1))
|
||||
) i_tcm (
|
||||
.clk (clk ),
|
||||
.rst_n (core_rst_n_local),
|
||||
|
||||
// Instruction interface to TCM
|
||||
.imem_req_ack (tcm_imem_req_ack),
|
||||
.imem_req (tcm_imem_req ),
|
||||
.imem_addr (tcm_imem_addr ),
|
||||
.imem_rdata (tcm_imem_rdata ),
|
||||
.imem_resp (tcm_imem_resp ),
|
||||
|
||||
// Data interface to TCM
|
||||
.dmem_req_ack (tcm_dmem_req_ack),
|
||||
.dmem_req (tcm_dmem_req ),
|
||||
.dmem_cmd (tcm_dmem_cmd ),
|
||||
.dmem_width (tcm_dmem_width ),
|
||||
.dmem_addr (tcm_dmem_addr ),
|
||||
.dmem_wdata (tcm_dmem_wdata ),
|
||||
.dmem_rdata (tcm_dmem_rdata ),
|
||||
.dmem_resp (tcm_dmem_resp )
|
||||
);
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Memory-mapped timer instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_timer i_timer (
|
||||
// Common
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
.rtc_clk (rtc_clk ),
|
||||
|
||||
// Memory interface
|
||||
.dmem_req (timer_dmem_req ),
|
||||
.dmem_cmd (timer_dmem_cmd ),
|
||||
.dmem_width (timer_dmem_width ),
|
||||
.dmem_addr (timer_dmem_addr ),
|
||||
.dmem_wdata (timer_dmem_wdata ),
|
||||
.dmem_req_ack (timer_dmem_req_ack),
|
||||
.dmem_rdata (timer_dmem_rdata ),
|
||||
.dmem_resp (timer_dmem_resp ),
|
||||
|
||||
// Timer interface
|
||||
.timer_val (timer_val ),
|
||||
.timer_irq (timer_irq )
|
||||
);
|
||||
|
||||
|
||||
`ifdef SCR1_IMEM_ROUTER_EN
|
||||
//-------------------------------------------------------------------------------
|
||||
// Instruction memory router
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_imem_router #(
|
||||
`ifdef SCR1_TCM_EN
|
||||
.SCR1_ADDR_MASK (SCR1_TCM_ADDR_MASK),
|
||||
.SCR1_ADDR_PATTERN (SCR1_TCM_ADDR_PATTERN)
|
||||
`endif // SCR1_TCM_EN
|
||||
) i_imem_router (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
// Interface to core
|
||||
.imem_req_ack (core_imem_req_ack),
|
||||
.imem_req (core_imem_req ),
|
||||
.imem_cmd (core_imem_cmd ),
|
||||
.imem_addr (core_imem_addr ),
|
||||
.imem_rdata (core_imem_rdata ),
|
||||
.imem_resp (core_imem_resp ),
|
||||
// Interface to AHB bridge
|
||||
.port0_req_ack (ahb_imem_req_ack ),
|
||||
.port0_req (ahb_imem_req ),
|
||||
.port0_cmd (ahb_imem_cmd ),
|
||||
.port0_addr (ahb_imem_addr ),
|
||||
.port0_rdata (ahb_imem_rdata ),
|
||||
.port0_resp (ahb_imem_resp ),
|
||||
`ifdef SCR1_TCM_EN
|
||||
// Interface to TCM
|
||||
.port1_req_ack (tcm_imem_req_ack ),
|
||||
.port1_req (tcm_imem_req ),
|
||||
.port1_cmd (tcm_imem_cmd ),
|
||||
.port1_addr (tcm_imem_addr ),
|
||||
.port1_rdata (tcm_imem_rdata ),
|
||||
.port1_resp (tcm_imem_resp )
|
||||
`endif // SCR1_TCM_EN
|
||||
);
|
||||
|
||||
`else // SCR1_IMEM_ROUTER_EN
|
||||
|
||||
assign ahb_imem_req = core_imem_req;
|
||||
assign ahb_imem_cmd = core_imem_cmd;
|
||||
assign ahb_imem_addr = core_imem_addr;
|
||||
assign core_imem_req_ack = ahb_imem_req_ack;
|
||||
assign core_imem_resp = ahb_imem_resp;
|
||||
assign core_imem_rdata = ahb_imem_rdata;
|
||||
|
||||
`endif // SCR1_IMEM_ROUTER_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Data memory router
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_dmem_router #(
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
.SCR1_PORT1_ADDR_MASK (SCR1_TCM_ADDR_MASK),
|
||||
.SCR1_PORT1_ADDR_PATTERN (SCR1_TCM_ADDR_PATTERN),
|
||||
`else // SCR1_TCM_EN
|
||||
.SCR1_PORT1_ADDR_MASK (32'h00000000),
|
||||
.SCR1_PORT1_ADDR_PATTERN (32'hFFFFFFFF),
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
.SCR1_PORT2_ADDR_MASK (SCR1_TIMER_ADDR_MASK),
|
||||
.SCR1_PORT2_ADDR_PATTERN (SCR1_TIMER_ADDR_PATTERN)
|
||||
|
||||
) i_dmem_router (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
// Interface to core
|
||||
.dmem_req_ack (core_dmem_req_ack ),
|
||||
.dmem_req (core_dmem_req ),
|
||||
.dmem_cmd (core_dmem_cmd ),
|
||||
.dmem_width (core_dmem_width ),
|
||||
.dmem_addr (core_dmem_addr ),
|
||||
.dmem_wdata (core_dmem_wdata ),
|
||||
.dmem_rdata (core_dmem_rdata ),
|
||||
.dmem_resp (core_dmem_resp ),
|
||||
`ifdef SCR1_TCM_EN
|
||||
// Interface to TCM
|
||||
.port1_req_ack (tcm_dmem_req_ack ),
|
||||
.port1_req (tcm_dmem_req ),
|
||||
.port1_cmd (tcm_dmem_cmd ),
|
||||
.port1_width (tcm_dmem_width ),
|
||||
.port1_addr (tcm_dmem_addr ),
|
||||
.port1_wdata (tcm_dmem_wdata ),
|
||||
.port1_rdata (tcm_dmem_rdata ),
|
||||
.port1_resp (tcm_dmem_resp ),
|
||||
`else // SCR1_TCM_EN
|
||||
.port1_req_ack (1'b0),
|
||||
.port1_req ( ),
|
||||
.port1_cmd ( ),
|
||||
.port1_width ( ),
|
||||
.port1_addr ( ),
|
||||
.port1_wdata ( ),
|
||||
.port1_rdata ('0 ),
|
||||
.port1_resp (SCR1_MEM_RESP_RDY_ER),
|
||||
`endif // SCR1_TCM_EN
|
||||
// Interface to memory-mapped timer
|
||||
.port2_req_ack (timer_dmem_req_ack ),
|
||||
.port2_req (timer_dmem_req ),
|
||||
.port2_cmd (timer_dmem_cmd ),
|
||||
.port2_width (timer_dmem_width ),
|
||||
.port2_addr (timer_dmem_addr ),
|
||||
.port2_wdata (timer_dmem_wdata ),
|
||||
.port2_rdata (timer_dmem_rdata ),
|
||||
.port2_resp (timer_dmem_resp ),
|
||||
// Interface to AHB bridge
|
||||
.port0_req_ack (ahb_dmem_req_ack ),
|
||||
.port0_req (ahb_dmem_req ),
|
||||
.port0_cmd (ahb_dmem_cmd ),
|
||||
.port0_width (ahb_dmem_width ),
|
||||
.port0_addr (ahb_dmem_addr ),
|
||||
.port0_wdata (ahb_dmem_wdata ),
|
||||
.port0_rdata (ahb_dmem_rdata ),
|
||||
.port0_resp (ahb_dmem_resp )
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Instruction memory AHB bridge
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_imem_ahb i_imem_ahb (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
// Interface to imem router
|
||||
.imem_req_ack (ahb_imem_req_ack ),
|
||||
.imem_req (ahb_imem_req ),
|
||||
.imem_addr (ahb_imem_addr ),
|
||||
.imem_rdata (ahb_imem_rdata ),
|
||||
.imem_resp (ahb_imem_resp ),
|
||||
// AHB interface
|
||||
.hprot (imem_hprot ),
|
||||
.hburst (imem_hburst ),
|
||||
.hsize (imem_hsize ),
|
||||
.htrans (imem_htrans ),
|
||||
.hmastlock (imem_hmastlock ),
|
||||
.haddr (imem_haddr ),
|
||||
.hready (imem_hready ),
|
||||
.hrdata (imem_hrdata ),
|
||||
.hresp (imem_hresp )
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Data memory AHB bridge
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_dmem_ahb i_dmem_ahb (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
// Interface to dmem router
|
||||
.dmem_req_ack (ahb_dmem_req_ack ),
|
||||
.dmem_req (ahb_dmem_req ),
|
||||
.dmem_cmd (ahb_dmem_cmd ),
|
||||
.dmem_width (ahb_dmem_width ),
|
||||
.dmem_addr (ahb_dmem_addr ),
|
||||
.dmem_wdata (ahb_dmem_wdata ),
|
||||
.dmem_rdata (ahb_dmem_rdata ),
|
||||
.dmem_resp (ahb_dmem_resp ),
|
||||
// AHB interface
|
||||
.hprot (dmem_hprot ),
|
||||
.hburst (dmem_hburst ),
|
||||
.hsize (dmem_hsize ),
|
||||
.htrans (dmem_htrans ),
|
||||
.hmastlock (dmem_hmastlock ),
|
||||
.haddr (dmem_haddr ),
|
||||
.hwrite (dmem_hwrite ),
|
||||
.hwdata (dmem_hwdata ),
|
||||
.hready (dmem_hready ),
|
||||
.hrdata (dmem_hrdata ),
|
||||
.hresp (dmem_hresp )
|
||||
);
|
||||
|
||||
endmodule : scr1_top_ahb
|
||||
|
||||
|
||||
701
src_ref/top/scr1_top_axi.sv
Normal file
701
src_ref/top/scr1_top_axi.sv
Normal file
@@ -0,0 +1,701 @@
|
||||
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
||||
/// @file <scr1_top_axi.sv>
|
||||
/// @brief SCR1 AXI top
|
||||
///
|
||||
|
||||
`include "scr1_arch_description.svh"
|
||||
`include "scr1_memif.svh"
|
||||
`ifdef SCR1_IPIC_EN
|
||||
`include "scr1_ipic.svh"
|
||||
`endif // SCR1_IPIC_EN
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
`define SCR1_IMEM_ROUTER_EN
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
module scr1_top_axi (
|
||||
// Control
|
||||
input logic pwrup_rst_n, // Power-Up Reset
|
||||
input logic rst_n, // Regular Reset signal
|
||||
input logic cpu_rst_n, // CPU Reset (Core Reset)
|
||||
input logic test_mode, // Test mode
|
||||
input logic test_rst_n, // Test mode's reset
|
||||
input logic clk, // System clock
|
||||
input logic rtc_clk, // Real-time clock
|
||||
`ifdef SCR1_DBG_EN
|
||||
output logic sys_rst_n_o, // External System Reset output
|
||||
// (for the processor cluster's components or
|
||||
// external SOC (could be useful in small
|
||||
// SCR-core-centric SOCs))
|
||||
output logic sys_rdc_qlfy_o, // System-to-External SOC Reset Domain Crossing Qualifier
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Fuses
|
||||
input logic [`SCR1_XLEN-1:0] fuse_mhartid, // Hart ID
|
||||
`ifdef SCR1_DBG_EN
|
||||
input logic [31:0] fuse_idcode, // TAPC IDCODE
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// IRQ
|
||||
`ifdef SCR1_IPIC_EN
|
||||
input logic [SCR1_IRQ_LINES_NUM-1:0] irq_lines, // IRQ lines to IPIC
|
||||
`else // SCR1_IPIC_EN
|
||||
input logic ext_irq, // External IRQ input
|
||||
`endif // SCR1_IPIC_EN
|
||||
input logic soft_irq, // Software IRQ input
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// -- JTAG I/F
|
||||
input logic trst_n,
|
||||
input logic tck,
|
||||
input logic tms,
|
||||
input logic tdi,
|
||||
output logic tdo,
|
||||
output logic tdo_en,
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction Memory Interface
|
||||
output logic [3:0] io_axi_imem_awid,
|
||||
output logic [31:0] io_axi_imem_awaddr,
|
||||
output logic [7:0] io_axi_imem_awlen,
|
||||
output logic [2:0] io_axi_imem_awsize,
|
||||
output logic [1:0] io_axi_imem_awburst,
|
||||
output logic io_axi_imem_awlock,
|
||||
output logic [3:0] io_axi_imem_awcache,
|
||||
output logic [2:0] io_axi_imem_awprot,
|
||||
output logic [3:0] io_axi_imem_awregion,
|
||||
output logic [3:0] io_axi_imem_awuser,
|
||||
output logic [3:0] io_axi_imem_awqos,
|
||||
output logic io_axi_imem_awvalid,
|
||||
input logic io_axi_imem_awready,
|
||||
output logic [31:0] io_axi_imem_wdata,
|
||||
output logic [3:0] io_axi_imem_wstrb,
|
||||
output logic io_axi_imem_wlast,
|
||||
output logic [3:0] io_axi_imem_wuser,
|
||||
output logic io_axi_imem_wvalid,
|
||||
input logic io_axi_imem_wready,
|
||||
input logic [3:0] io_axi_imem_bid,
|
||||
input logic [1:0] io_axi_imem_bresp,
|
||||
input logic io_axi_imem_bvalid,
|
||||
input logic [3:0] io_axi_imem_buser,
|
||||
output logic io_axi_imem_bready,
|
||||
output logic [3:0] io_axi_imem_arid,
|
||||
output logic [31:0] io_axi_imem_araddr,
|
||||
output logic [7:0] io_axi_imem_arlen,
|
||||
output logic [2:0] io_axi_imem_arsize,
|
||||
output logic [1:0] io_axi_imem_arburst,
|
||||
output logic io_axi_imem_arlock,
|
||||
output logic [3:0] io_axi_imem_arcache,
|
||||
output logic [2:0] io_axi_imem_arprot,
|
||||
output logic [3:0] io_axi_imem_arregion,
|
||||
output logic [3:0] io_axi_imem_aruser,
|
||||
output logic [3:0] io_axi_imem_arqos,
|
||||
output logic io_axi_imem_arvalid,
|
||||
input logic io_axi_imem_arready,
|
||||
input logic [3:0] io_axi_imem_rid,
|
||||
input logic [31:0] io_axi_imem_rdata,
|
||||
input logic [1:0] io_axi_imem_rresp,
|
||||
input logic io_axi_imem_rlast,
|
||||
input logic [3:0] io_axi_imem_ruser,
|
||||
input logic io_axi_imem_rvalid,
|
||||
output logic io_axi_imem_rready,
|
||||
|
||||
// Data Memory Interface
|
||||
output logic [3:0] io_axi_dmem_awid,
|
||||
output logic [31:0] io_axi_dmem_awaddr,
|
||||
output logic [7:0] io_axi_dmem_awlen,
|
||||
output logic [2:0] io_axi_dmem_awsize,
|
||||
output logic [1:0] io_axi_dmem_awburst,
|
||||
output logic io_axi_dmem_awlock,
|
||||
output logic [3:0] io_axi_dmem_awcache,
|
||||
output logic [2:0] io_axi_dmem_awprot,
|
||||
output logic [3:0] io_axi_dmem_awregion,
|
||||
output logic [3:0] io_axi_dmem_awuser,
|
||||
output logic [3:0] io_axi_dmem_awqos,
|
||||
output logic io_axi_dmem_awvalid,
|
||||
input logic io_axi_dmem_awready,
|
||||
output logic [31:0] io_axi_dmem_wdata,
|
||||
output logic [3:0] io_axi_dmem_wstrb,
|
||||
output logic io_axi_dmem_wlast,
|
||||
output logic [3:0] io_axi_dmem_wuser,
|
||||
output logic io_axi_dmem_wvalid,
|
||||
input logic io_axi_dmem_wready,
|
||||
input logic [3:0] io_axi_dmem_bid,
|
||||
input logic [1:0] io_axi_dmem_bresp,
|
||||
input logic io_axi_dmem_bvalid,
|
||||
input logic [3:0] io_axi_dmem_buser,
|
||||
output logic io_axi_dmem_bready,
|
||||
output logic [3:0] io_axi_dmem_arid,
|
||||
output logic [31:0] io_axi_dmem_araddr,
|
||||
output logic [7:0] io_axi_dmem_arlen,
|
||||
output logic [2:0] io_axi_dmem_arsize,
|
||||
output logic [1:0] io_axi_dmem_arburst,
|
||||
output logic io_axi_dmem_arlock,
|
||||
output logic [3:0] io_axi_dmem_arcache,
|
||||
output logic [2:0] io_axi_dmem_arprot,
|
||||
output logic [3:0] io_axi_dmem_arregion,
|
||||
output logic [3:0] io_axi_dmem_aruser,
|
||||
output logic [3:0] io_axi_dmem_arqos,
|
||||
output logic io_axi_dmem_arvalid,
|
||||
input logic io_axi_dmem_arready,
|
||||
input logic [3:0] io_axi_dmem_rid,
|
||||
input logic [31:0] io_axi_dmem_rdata,
|
||||
input logic [1:0] io_axi_dmem_rresp,
|
||||
input logic io_axi_dmem_rlast,
|
||||
input logic [3:0] io_axi_dmem_ruser,
|
||||
input logic io_axi_dmem_rvalid,
|
||||
output logic io_axi_dmem_rready
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local parameters
|
||||
//-------------------------------------------------------------------------------
|
||||
localparam int unsigned SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM = 2;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Local signal declaration
|
||||
//-------------------------------------------------------------------------------
|
||||
// Reset logic
|
||||
logic pwrup_rst_n_sync;
|
||||
logic rst_n_sync;
|
||||
logic cpu_rst_n_sync;
|
||||
logic core_rst_n_local;
|
||||
logic axi_rst_n;
|
||||
`ifdef SCR1_DBG_EN
|
||||
logic tapc_trst_n;
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction memory interface from core to router
|
||||
logic core_imem_req_ack;
|
||||
logic core_imem_req;
|
||||
type_scr1_mem_cmd_e core_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] core_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] core_imem_rdata;
|
||||
type_scr1_mem_resp_e core_imem_resp;
|
||||
|
||||
// Data memory interface from core to router
|
||||
logic core_dmem_req_ack;
|
||||
logic core_dmem_req;
|
||||
type_scr1_mem_cmd_e core_dmem_cmd;
|
||||
type_scr1_mem_width_e core_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] core_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] core_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] core_dmem_rdata;
|
||||
type_scr1_mem_resp_e core_dmem_resp;
|
||||
|
||||
// Instruction memory interface from router to AXI bridge
|
||||
logic axi_imem_req_ack;
|
||||
logic axi_imem_req;
|
||||
type_scr1_mem_cmd_e axi_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] axi_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] axi_imem_rdata;
|
||||
type_scr1_mem_resp_e axi_imem_resp;
|
||||
|
||||
// Data memory interface from router to AXI bridge
|
||||
logic axi_dmem_req_ack;
|
||||
logic axi_dmem_req;
|
||||
type_scr1_mem_cmd_e axi_dmem_cmd;
|
||||
type_scr1_mem_width_e axi_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] axi_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] axi_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] axi_dmem_rdata;
|
||||
type_scr1_mem_resp_e axi_dmem_resp;
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
// Instruction memory interface from router to TCM
|
||||
logic tcm_imem_req_ack;
|
||||
logic tcm_imem_req;
|
||||
type_scr1_mem_cmd_e tcm_imem_cmd;
|
||||
logic [`SCR1_IMEM_AWIDTH-1:0] tcm_imem_addr;
|
||||
logic [`SCR1_IMEM_DWIDTH-1:0] tcm_imem_rdata;
|
||||
type_scr1_mem_resp_e tcm_imem_resp;
|
||||
|
||||
// Data memory interface from router to TCM
|
||||
logic tcm_dmem_req_ack;
|
||||
logic tcm_dmem_req;
|
||||
type_scr1_mem_cmd_e tcm_dmem_cmd;
|
||||
type_scr1_mem_width_e tcm_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] tcm_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] tcm_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] tcm_dmem_rdata;
|
||||
type_scr1_mem_resp_e tcm_dmem_resp;
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
// Data memory interface from router to memory-mapped timer
|
||||
logic timer_dmem_req_ack;
|
||||
logic timer_dmem_req;
|
||||
type_scr1_mem_cmd_e timer_dmem_cmd;
|
||||
type_scr1_mem_width_e timer_dmem_width;
|
||||
logic [`SCR1_DMEM_AWIDTH-1:0] timer_dmem_addr;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] timer_dmem_wdata;
|
||||
logic [`SCR1_DMEM_DWIDTH-1:0] timer_dmem_rdata;
|
||||
type_scr1_mem_resp_e timer_dmem_resp;
|
||||
|
||||
// Misc
|
||||
logic timer_irq;
|
||||
logic [63:0] timer_val;
|
||||
logic axi_reinit;
|
||||
logic axi_imem_idle;
|
||||
logic axi_dmem_idle;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Reset logic
|
||||
//-------------------------------------------------------------------------------
|
||||
// Power-Up Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_pwrup_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (1'b1 ),
|
||||
.rst_n_out (pwrup_rst_n_sync)
|
||||
);
|
||||
|
||||
// Regular Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (rst_n ),
|
||||
.rst_n_out (rst_n_sync )
|
||||
);
|
||||
|
||||
// CPU Reset synchronizer
|
||||
scr1_reset_sync_cell #(
|
||||
.STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
|
||||
) i_cpu_rstn_reset_sync (
|
||||
.rst_n (pwrup_rst_n ),
|
||||
.clk (clk ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_in (cpu_rst_n ),
|
||||
.rst_n_out (cpu_rst_n_sync )
|
||||
);
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// TAPC Reset
|
||||
scr1_reset_and2_cell i_tapc_rstn_and2_cell (
|
||||
.rst_n_in ({trst_n, pwrup_rst_n}),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.test_mode (test_mode ),
|
||||
.rst_n_out (tapc_trst_n )
|
||||
);
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
assign axi_rst_n = sys_rst_n_o;
|
||||
`else // SCR1_DBG_EN
|
||||
assign axi_rst_n = rst_n_sync;
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// SCR1 core instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_core_top i_core_top (
|
||||
// Common
|
||||
.pwrup_rst_n (pwrup_rst_n_sync ),
|
||||
.rst_n (rst_n_sync ),
|
||||
.cpu_rst_n (cpu_rst_n_sync ),
|
||||
.test_mode (test_mode ),
|
||||
.test_rst_n (test_rst_n ),
|
||||
.clk (clk ),
|
||||
.core_rst_n_o (core_rst_n_local ),
|
||||
.core_rdc_qlfy_o ( ),
|
||||
`ifdef SCR1_DBG_EN
|
||||
.sys_rst_n_o (sys_rst_n_o ),
|
||||
.sys_rdc_qlfy_o (sys_rdc_qlfy_o ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Fuses
|
||||
.core_fuse_mhartid_i (fuse_mhartid ),
|
||||
`ifdef SCR1_DBG_EN
|
||||
.tapc_fuse_idcode_i (fuse_idcode ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// IRQ
|
||||
`ifdef SCR1_IPIC_EN
|
||||
.core_irq_lines_i (irq_lines ),
|
||||
`else // SCR1_IPIC_EN
|
||||
.core_irq_ext_i (ext_irq ),
|
||||
`endif // SCR1_IPIC_EN
|
||||
.core_irq_soft_i (soft_irq ),
|
||||
.core_irq_mtimer_i (timer_irq ),
|
||||
|
||||
// Memory-mapped external timer
|
||||
.core_mtimer_val_i (timer_val ),
|
||||
|
||||
`ifdef SCR1_DBG_EN
|
||||
// Debug interface
|
||||
.tapc_trst_n (tapc_trst_n ),
|
||||
.tapc_tck (tck ),
|
||||
.tapc_tms (tms ),
|
||||
.tapc_tdi (tdi ),
|
||||
.tapc_tdo (tdo ),
|
||||
.tapc_tdo_en (tdo_en ),
|
||||
`endif // SCR1_DBG_EN
|
||||
|
||||
// Instruction memory interface
|
||||
.imem2core_req_ack_i (core_imem_req_ack),
|
||||
.core2imem_req_o (core_imem_req ),
|
||||
.core2imem_cmd_o (core_imem_cmd ),
|
||||
.core2imem_addr_o (core_imem_addr ),
|
||||
.imem2core_rdata_i (core_imem_rdata ),
|
||||
.imem2core_resp_i (core_imem_resp ),
|
||||
|
||||
// Data memory interface
|
||||
.dmem2core_req_ack_i (core_dmem_req_ack),
|
||||
.core2dmem_req_o (core_dmem_req ),
|
||||
.core2dmem_cmd_o (core_dmem_cmd ),
|
||||
.core2dmem_width_o (core_dmem_width ),
|
||||
.core2dmem_addr_o (core_dmem_addr ),
|
||||
.core2dmem_wdata_o (core_dmem_wdata ),
|
||||
.dmem2core_rdata_i (core_dmem_rdata ),
|
||||
.dmem2core_resp_i (core_dmem_resp )
|
||||
);
|
||||
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
//-------------------------------------------------------------------------------
|
||||
// TCM instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_tcm #(
|
||||
.SCR1_TCM_SIZE (`SCR1_DMEM_AWIDTH'(~SCR1_TCM_ADDR_MASK + 1'b1))
|
||||
) i_tcm (
|
||||
.clk (clk ),
|
||||
.rst_n (core_rst_n_local),
|
||||
|
||||
// Instruction interface to TCM
|
||||
.imem_req_ack (tcm_imem_req_ack),
|
||||
.imem_req (tcm_imem_req ),
|
||||
.imem_addr (tcm_imem_addr ),
|
||||
.imem_rdata (tcm_imem_rdata ),
|
||||
.imem_resp (tcm_imem_resp ),
|
||||
|
||||
// Data interface to TCM
|
||||
.dmem_req_ack (tcm_dmem_req_ack),
|
||||
.dmem_req (tcm_dmem_req ),
|
||||
.dmem_cmd (tcm_dmem_cmd ),
|
||||
.dmem_width (tcm_dmem_width ),
|
||||
.dmem_addr (tcm_dmem_addr ),
|
||||
.dmem_wdata (tcm_dmem_wdata ),
|
||||
.dmem_rdata (tcm_dmem_rdata ),
|
||||
.dmem_resp (tcm_dmem_resp )
|
||||
);
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Memory-mapped timer instance
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_timer i_timer (
|
||||
// Common
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
.rtc_clk (rtc_clk ),
|
||||
|
||||
// Memory interface
|
||||
.dmem_req (timer_dmem_req ),
|
||||
.dmem_cmd (timer_dmem_cmd ),
|
||||
.dmem_width (timer_dmem_width ),
|
||||
.dmem_addr (timer_dmem_addr ),
|
||||
.dmem_wdata (timer_dmem_wdata ),
|
||||
.dmem_req_ack (timer_dmem_req_ack),
|
||||
.dmem_rdata (timer_dmem_rdata ),
|
||||
.dmem_resp (timer_dmem_resp ),
|
||||
|
||||
// Timer interface
|
||||
.timer_val (timer_val ),
|
||||
.timer_irq (timer_irq )
|
||||
);
|
||||
|
||||
|
||||
`ifdef SCR1_IMEM_ROUTER_EN
|
||||
//-------------------------------------------------------------------------------
|
||||
// Instruction memory router
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_imem_router #(
|
||||
.SCR1_ADDR_MASK (SCR1_TCM_ADDR_MASK),
|
||||
.SCR1_ADDR_PATTERN (SCR1_TCM_ADDR_PATTERN)
|
||||
) i_imem_router (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
|
||||
// Interface to core
|
||||
.imem_req_ack (core_imem_req_ack),
|
||||
.imem_req (core_imem_req ),
|
||||
.imem_cmd (core_imem_cmd ),
|
||||
.imem_addr (core_imem_addr ),
|
||||
.imem_rdata (core_imem_rdata ),
|
||||
.imem_resp (core_imem_resp ),
|
||||
|
||||
// Interface to AXI bridge
|
||||
.port0_req_ack (axi_imem_req_ack ),
|
||||
.port0_req (axi_imem_req ),
|
||||
.port0_cmd (axi_imem_cmd ),
|
||||
.port0_addr (axi_imem_addr ),
|
||||
.port0_rdata (axi_imem_rdata ),
|
||||
.port0_resp (axi_imem_resp ),
|
||||
|
||||
// Interface to TCM
|
||||
.port1_req_ack (tcm_imem_req_ack ),
|
||||
.port1_req (tcm_imem_req ),
|
||||
.port1_cmd (tcm_imem_cmd ),
|
||||
.port1_addr (tcm_imem_addr ),
|
||||
.port1_rdata (tcm_imem_rdata ),
|
||||
.port1_resp (tcm_imem_resp )
|
||||
);
|
||||
|
||||
`else // SCR1_IMEM_ROUTER_EN
|
||||
|
||||
assign axi_imem_req = core_imem_req;
|
||||
assign axi_imem_cmd = core_imem_cmd;
|
||||
assign axi_imem_addr = core_imem_addr;
|
||||
assign core_imem_req_ack = axi_imem_req_ack;
|
||||
assign core_imem_resp = axi_imem_resp;
|
||||
assign core_imem_rdata = axi_imem_rdata;
|
||||
|
||||
`endif // SCR1_IMEM_ROUTER_EN
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Data memory router
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_dmem_router #(
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
.SCR1_PORT1_ADDR_MASK (SCR1_TCM_ADDR_MASK),
|
||||
.SCR1_PORT1_ADDR_PATTERN (SCR1_TCM_ADDR_PATTERN),
|
||||
`else // SCR1_TCM_EN
|
||||
.SCR1_PORT1_ADDR_MASK (32'h00000000),
|
||||
.SCR1_PORT1_ADDR_PATTERN (32'hFFFFFFFF),
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
.SCR1_PORT2_ADDR_MASK (SCR1_TIMER_ADDR_MASK),
|
||||
.SCR1_PORT2_ADDR_PATTERN (SCR1_TIMER_ADDR_PATTERN)
|
||||
|
||||
) i_dmem_router (
|
||||
.rst_n (core_rst_n_local ),
|
||||
.clk (clk ),
|
||||
|
||||
// Interface to core
|
||||
.dmem_req_ack (core_dmem_req_ack ),
|
||||
.dmem_req (core_dmem_req ),
|
||||
.dmem_cmd (core_dmem_cmd ),
|
||||
.dmem_width (core_dmem_width ),
|
||||
.dmem_addr (core_dmem_addr ),
|
||||
.dmem_wdata (core_dmem_wdata ),
|
||||
.dmem_rdata (core_dmem_rdata ),
|
||||
.dmem_resp (core_dmem_resp ),
|
||||
|
||||
`ifdef SCR1_TCM_EN
|
||||
// Interface to TCM
|
||||
.port1_req_ack (tcm_dmem_req_ack ),
|
||||
.port1_req (tcm_dmem_req ),
|
||||
.port1_cmd (tcm_dmem_cmd ),
|
||||
.port1_width (tcm_dmem_width ),
|
||||
.port1_addr (tcm_dmem_addr ),
|
||||
.port1_wdata (tcm_dmem_wdata ),
|
||||
.port1_rdata (tcm_dmem_rdata ),
|
||||
.port1_resp (tcm_dmem_resp ),
|
||||
`else // SCR1_TCM_EN
|
||||
.port1_req_ack (1'b0 ),
|
||||
.port1_req ( ),
|
||||
.port1_cmd ( ),
|
||||
.port1_width ( ),
|
||||
.port1_addr ( ),
|
||||
.port1_wdata ( ),
|
||||
.port1_rdata ('0 ),
|
||||
.port1_resp (SCR1_MEM_RESP_RDY_ER),
|
||||
`endif // SCR1_TCM_EN
|
||||
|
||||
// Interface to memory-mapped timer
|
||||
.port2_req_ack (timer_dmem_req_ack ),
|
||||
.port2_req (timer_dmem_req ),
|
||||
.port2_cmd (timer_dmem_cmd ),
|
||||
.port2_width (timer_dmem_width ),
|
||||
.port2_addr (timer_dmem_addr ),
|
||||
.port2_wdata (timer_dmem_wdata ),
|
||||
.port2_rdata (timer_dmem_rdata ),
|
||||
.port2_resp (timer_dmem_resp ),
|
||||
|
||||
// Interface to AXI bridge
|
||||
.port0_req_ack (axi_dmem_req_ack ),
|
||||
.port0_req (axi_dmem_req ),
|
||||
.port0_cmd (axi_dmem_cmd ),
|
||||
.port0_width (axi_dmem_width ),
|
||||
.port0_addr (axi_dmem_addr ),
|
||||
.port0_wdata (axi_dmem_wdata ),
|
||||
.port0_rdata (axi_dmem_rdata ),
|
||||
.port0_resp (axi_dmem_resp )
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Instruction memory AXI bridge
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_mem_axi #(
|
||||
`ifdef SCR1_IMEM_AXI_REQ_BP
|
||||
.SCR1_AXI_REQ_BP (1),
|
||||
`else // SCR1_IMEM_AXI_REQ_BP
|
||||
.SCR1_AXI_REQ_BP (0),
|
||||
`endif // SCR1_IMEM_AXI_REQ_BP
|
||||
`ifdef SCR1_IMEM_AXI_RESP_BP
|
||||
.SCR1_AXI_RESP_BP (1)
|
||||
`else // SCR1_IMEM_AXI_RESP_BP
|
||||
.SCR1_AXI_RESP_BP (0)
|
||||
`endif // SCR1_IMEM_AXI_RESP_BP
|
||||
) i_imem_axi (
|
||||
.clk (clk ),
|
||||
.rst_n (axi_rst_n ),
|
||||
.axi_reinit (axi_reinit ),
|
||||
|
||||
// Interface to core
|
||||
.core_idle (axi_imem_idle ),
|
||||
.core_req_ack (axi_imem_req_ack ),
|
||||
.core_req (axi_imem_req ),
|
||||
.core_cmd (axi_imem_cmd ),
|
||||
.core_width (SCR1_MEM_WIDTH_WORD ),
|
||||
.core_addr (axi_imem_addr ),
|
||||
.core_wdata ('0 ),
|
||||
.core_rdata (axi_imem_rdata ),
|
||||
.core_resp (axi_imem_resp ),
|
||||
|
||||
// AXI I/O
|
||||
.awid (io_axi_imem_awid ),
|
||||
.awaddr (io_axi_imem_awaddr ),
|
||||
.awlen (io_axi_imem_awlen ),
|
||||
.awsize (io_axi_imem_awsize ),
|
||||
.awburst (io_axi_imem_awburst ),
|
||||
.awlock (io_axi_imem_awlock ),
|
||||
.awcache (io_axi_imem_awcache ),
|
||||
.awprot (io_axi_imem_awprot ),
|
||||
.awregion (io_axi_imem_awregion ),
|
||||
.awuser (io_axi_imem_awuser ),
|
||||
.awqos (io_axi_imem_awqos ),
|
||||
.awvalid (io_axi_imem_awvalid ),
|
||||
.awready (io_axi_imem_awready ),
|
||||
.wdata (io_axi_imem_wdata ),
|
||||
.wstrb (io_axi_imem_wstrb ),
|
||||
.wlast (io_axi_imem_wlast ),
|
||||
.wuser (io_axi_imem_wuser ),
|
||||
.wvalid (io_axi_imem_wvalid ),
|
||||
.wready (io_axi_imem_wready ),
|
||||
.bid (io_axi_imem_bid ),
|
||||
.bresp (io_axi_imem_bresp ),
|
||||
.bvalid (io_axi_imem_bvalid ),
|
||||
.buser (io_axi_imem_buser ),
|
||||
.bready (io_axi_imem_bready ),
|
||||
.arid (io_axi_imem_arid ),
|
||||
.araddr (io_axi_imem_araddr ),
|
||||
.arlen (io_axi_imem_arlen ),
|
||||
.arsize (io_axi_imem_arsize ),
|
||||
.arburst (io_axi_imem_arburst ),
|
||||
.arlock (io_axi_imem_arlock ),
|
||||
.arcache (io_axi_imem_arcache ),
|
||||
.arprot (io_axi_imem_arprot ),
|
||||
.arregion (io_axi_imem_arregion ),
|
||||
.aruser (io_axi_imem_aruser ),
|
||||
.arqos (io_axi_imem_arqos ),
|
||||
.arvalid (io_axi_imem_arvalid ),
|
||||
.arready (io_axi_imem_arready ),
|
||||
.rid (io_axi_imem_rid ),
|
||||
.rdata (io_axi_imem_rdata ),
|
||||
.rresp (io_axi_imem_rresp ),
|
||||
.rlast (io_axi_imem_rlast ),
|
||||
.ruser (io_axi_imem_ruser ),
|
||||
.rvalid (io_axi_imem_rvalid ),
|
||||
.rready (io_axi_imem_rready )
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Data memory AXI bridge
|
||||
//-------------------------------------------------------------------------------
|
||||
scr1_mem_axi #(
|
||||
`ifdef SCR1_DMEM_AXI_REQ_BP
|
||||
.SCR1_AXI_REQ_BP (1),
|
||||
`else // SCR1_DMEM_AXI_REQ_BP
|
||||
.SCR1_AXI_REQ_BP (0),
|
||||
`endif // SCR1_DMEM_AXI_REQ_BP
|
||||
`ifdef SCR1_DMEM_AXI_RESP_BP
|
||||
.SCR1_AXI_RESP_BP (1)
|
||||
`else // SCR1_DMEM_AXI_RESP_BP
|
||||
.SCR1_AXI_RESP_BP (0)
|
||||
`endif // SCR1_DMEM_AXI_RESP_BP
|
||||
) i_dmem_axi (
|
||||
.clk (clk ),
|
||||
.rst_n (axi_rst_n ),
|
||||
.axi_reinit (axi_reinit ),
|
||||
|
||||
// Interface to core
|
||||
.core_idle (axi_dmem_idle ),
|
||||
.core_req_ack (axi_dmem_req_ack ),
|
||||
.core_req (axi_dmem_req ),
|
||||
.core_cmd (axi_dmem_cmd ),
|
||||
.core_width (axi_dmem_width ),
|
||||
.core_addr (axi_dmem_addr ),
|
||||
.core_wdata (axi_dmem_wdata ),
|
||||
.core_rdata (axi_dmem_rdata ),
|
||||
.core_resp (axi_dmem_resp ),
|
||||
|
||||
// AXI I/O
|
||||
.awid (io_axi_dmem_awid ),
|
||||
.awaddr (io_axi_dmem_awaddr ),
|
||||
.awlen (io_axi_dmem_awlen ),
|
||||
.awsize (io_axi_dmem_awsize ),
|
||||
.awburst (io_axi_dmem_awburst ),
|
||||
.awlock (io_axi_dmem_awlock ),
|
||||
.awcache (io_axi_dmem_awcache ),
|
||||
.awprot (io_axi_dmem_awprot ),
|
||||
.awregion (io_axi_dmem_awregion ),
|
||||
.awuser (io_axi_dmem_awuser ),
|
||||
.awqos (io_axi_dmem_awqos ),
|
||||
.awvalid (io_axi_dmem_awvalid ),
|
||||
.awready (io_axi_dmem_awready ),
|
||||
.wdata (io_axi_dmem_wdata ),
|
||||
.wstrb (io_axi_dmem_wstrb ),
|
||||
.wlast (io_axi_dmem_wlast ),
|
||||
.wuser (io_axi_dmem_wuser ),
|
||||
.wvalid (io_axi_dmem_wvalid ),
|
||||
.wready (io_axi_dmem_wready ),
|
||||
.bid (io_axi_dmem_bid ),
|
||||
.bresp (io_axi_dmem_bresp ),
|
||||
.bvalid (io_axi_dmem_bvalid ),
|
||||
.buser (io_axi_dmem_buser ),
|
||||
.bready (io_axi_dmem_bready ),
|
||||
.arid (io_axi_dmem_arid ),
|
||||
.araddr (io_axi_dmem_araddr ),
|
||||
.arlen (io_axi_dmem_arlen ),
|
||||
.arsize (io_axi_dmem_arsize ),
|
||||
.arburst (io_axi_dmem_arburst ),
|
||||
.arlock (io_axi_dmem_arlock ),
|
||||
.arcache (io_axi_dmem_arcache ),
|
||||
.arprot (io_axi_dmem_arprot ),
|
||||
.arregion (io_axi_dmem_arregion ),
|
||||
.aruser (io_axi_dmem_aruser ),
|
||||
.arqos (io_axi_dmem_arqos ),
|
||||
.arvalid (io_axi_dmem_arvalid ),
|
||||
.arready (io_axi_dmem_arready ),
|
||||
.rid (io_axi_dmem_rid ),
|
||||
.rdata (io_axi_dmem_rdata ),
|
||||
.rresp (io_axi_dmem_rresp ),
|
||||
.rlast (io_axi_dmem_rlast ),
|
||||
.ruser (io_axi_dmem_ruser ),
|
||||
.rvalid (io_axi_dmem_rvalid ),
|
||||
.rready (io_axi_dmem_rready )
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// AXI reinit logic
|
||||
//-------------------------------------------------------------------------------
|
||||
always_ff @(negedge core_rst_n_local, posedge clk) begin
|
||||
if (~core_rst_n_local) axi_reinit <= 1'b1;
|
||||
else if (axi_imem_idle & axi_dmem_idle) axi_reinit <= 1'b0;
|
||||
end
|
||||
|
||||
endmodule : scr1_top_axi
|
||||
Reference in New Issue
Block a user