mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-22 13:07:33 -04:00
solving axi rmw problem plus the axi plic and clint connections
This commit is contained in:
parent
0a9ccd476a
commit
c60027995d
7 changed files with 376 additions and 118 deletions
|
@ -61,6 +61,7 @@ module multicore_arbiter
|
|||
logic[3:0] wbe;
|
||||
logic[31:0] wdata;
|
||||
full_id_t id;
|
||||
logic rmw;
|
||||
} request_t;
|
||||
request_t in_req;
|
||||
request_t out_req;
|
||||
|
@ -71,6 +72,7 @@ module multicore_arbiter
|
|||
logic[NUM_CORES-1:0][31:2] addr;
|
||||
logic[NUM_CORES-1:0][4:0] rlen;
|
||||
logic[NUM_CORES-1:0] rnw;
|
||||
logic[NUM_CORES-1:0] rmw;
|
||||
logic[NUM_CORES-1:0][3:0] wbe;
|
||||
logic[NUM_CORES-1:0][31:0] wdata;
|
||||
logic[NUM_CORES-1:0][1:0] id;
|
||||
|
@ -96,6 +98,7 @@ module multicore_arbiter
|
|||
assign addr[i] = mems[i].addr;
|
||||
assign rlen[i] = mems[i].rlen;
|
||||
assign rnw[i] = mems[i].rnw;
|
||||
assign rmw[i] = mems[i].rmw;
|
||||
assign wbe[i] = mems[i].wbe;
|
||||
assign wdata[i] = mems[i].wdata;
|
||||
assign id[i] = mems[i].id;
|
||||
|
@ -108,9 +111,54 @@ module multicore_arbiter
|
|||
assign mems[i].rid = request_rid[1:0];
|
||||
assign mems[i].write_outstanding = wcounts[i][$clog2(FIFO_DEPTH)] | write_outstanding[i];
|
||||
end endgenerate
|
||||
|
||||
logic [4:0] rmw_len;
|
||||
logic [31:2] rmw_addr;
|
||||
logic [1:0] rmw_index;
|
||||
always_ff @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
rmw_len <= '0;
|
||||
rmw_addr <= '0;
|
||||
rmw_index <= '0;
|
||||
end
|
||||
else if (in_req.rmw & in_req.rnw & request_push) begin
|
||||
rmw_addr <= in_req.addr;
|
||||
rmw_len <= in_req.rlen;
|
||||
rmw_index <= chosen_port;
|
||||
end
|
||||
end
|
||||
|
||||
//Request FIFO
|
||||
assign request_push = ~request_fifo.full & |requests;
|
||||
logic[1:0] rmw_in_fifo;
|
||||
always_ff @(posedge clk or posedge rst) begin
|
||||
if (rst)
|
||||
rmw_in_fifo <= 0;
|
||||
else if (rmw_in_fifo == 2)begin
|
||||
if(rmw_counter == rmw_len+1)
|
||||
rmw_in_fifo <= 0;
|
||||
else
|
||||
rmw_in_fifo <= 2;
|
||||
end else if (in_req.rmw & in_req.rnw & request_push)
|
||||
rmw_in_fifo <= 1;
|
||||
else if (out_req.rmw & out_req.rnw & request_pop)
|
||||
rmw_in_fifo <= 2;
|
||||
end
|
||||
|
||||
logic [4:0] rmw_counter;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst)begin
|
||||
rmw_counter <= '0;
|
||||
end else if(rmw_in_fifo==2) begin
|
||||
if(rvalids[rmw_index])
|
||||
rmw_counter <= rmw_counter + 1;
|
||||
else
|
||||
rmw_counter <= rmw_counter;
|
||||
end else begin
|
||||
rmw_counter <= '0;
|
||||
end
|
||||
end
|
||||
|
||||
assign request_push = ~request_fifo.full & |requests & ((rmw_in_fifo==0) | in_req.rnw | rmw_addr[31:6] != in_req.addr[31:6]);
|
||||
assign request_fifo.data_in = in_req;
|
||||
assign out_req = request_fifo.data_out;
|
||||
assign request_valid = request_fifo.valid;
|
||||
|
@ -140,7 +188,8 @@ module multicore_arbiter
|
|||
rnw : rnw[chosen_port],
|
||||
wbe : wbe[chosen_port],
|
||||
wdata : wdata[chosen_port],
|
||||
id : padded_id
|
||||
id : padded_id,
|
||||
rmw : rmw[chosen_port]
|
||||
};
|
||||
|
||||
generate if (NUM_CORES == 1) begin : gen_no_id
|
||||
|
|
|
@ -25,7 +25,7 @@ module clint_wrapper
|
|||
|
||||
#(
|
||||
parameter int unsigned NUM_CORES = 1,
|
||||
parameter logic AXI = 1'b0 //Else the wishbone bus is used
|
||||
parameter logic AXI = 1'b1 //Else the wishbone bus is used
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
@ -46,20 +46,20 @@ module clint_wrapper
|
|||
output logic wb_ack,
|
||||
|
||||
//Compliant AXI Lite interface; does not include optional awprot, wstrb, bresp, arprot, and rresp
|
||||
input logic axi_awvalid,
|
||||
input logic[15:2] axi_awaddr,
|
||||
output logic axi_awready,
|
||||
input logic axi_wvalid,
|
||||
input logic[31:0] axi_wdata,
|
||||
output logic axi_wready,
|
||||
output logic axi_bvalid,
|
||||
input logic axi_bready,
|
||||
input logic axi_arvalid,
|
||||
input logic[15:2] axi_araddr,
|
||||
output logic axi_arready,
|
||||
output logic axi_rvalid,
|
||||
output logic[31:0] axi_rdata,
|
||||
input logic axi_rready
|
||||
input logic S_AXI_awvalid,
|
||||
input logic[31:0] S_AXI_awaddr,
|
||||
output logic S_AXI_awready,
|
||||
input logic S_AXI_wvalid,
|
||||
input logic[31:0] S_AXI_wdata,
|
||||
output logic S_AXI_wready,
|
||||
output logic S_AXI_bvalid,
|
||||
input logic S_AXI_bready,
|
||||
input logic S_AXI_arvalid,
|
||||
input logic[31:0] S_AXI_araddr,
|
||||
output logic S_AXI_arready,
|
||||
output logic S_AXI_rvalid,
|
||||
output logic[31:0] S_AXI_rdata,
|
||||
input logic S_AXI_rready
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -100,50 +100,103 @@ module clint_wrapper
|
|||
|
||||
|
||||
//Interface
|
||||
generate if (AXI) begin : gen_axi_if
|
||||
generate if (AXI) begin : gen_S_AXI_if
|
||||
//Simple implementation uses single-cycle for reads and writes
|
||||
logic doing_write;
|
||||
assign doing_write = axi_awvalid & axi_awready & axi_wvalid & axi_wready;
|
||||
typedef enum logic [2:0] {
|
||||
IDLE,
|
||||
RADDR,
|
||||
WADDR,
|
||||
RDATA,
|
||||
WDATA
|
||||
} state_t;
|
||||
|
||||
//Outputs
|
||||
assign axi_arready = ~axi_rvalid;
|
||||
assign axi_awready = ~axi_bvalid & ~axi_arvalid & axi_awvalid & axi_wvalid;
|
||||
assign axi_wready = axi_awready;
|
||||
state_t state, next_state;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
axi_rvalid <= 0;
|
||||
axi_bvalid <= 0;
|
||||
state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
axi_rvalid <= axi_rvalid ? ~axi_rready : axi_arvalid;
|
||||
axi_bvalid <= axi_bvalid ? ~axi_bready : doing_write;
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
case (state) inside
|
||||
IDLE : begin
|
||||
if (S_AXI_awvalid) begin
|
||||
next_state = WADDR;
|
||||
end
|
||||
else if (S_AXI_arvalid) begin
|
||||
next_state = RADDR;
|
||||
end
|
||||
end
|
||||
RADDR : begin
|
||||
if (S_AXI_arready) begin
|
||||
next_state = RDATA;
|
||||
end
|
||||
end
|
||||
WADDR : begin
|
||||
if (S_AXI_wvalid) begin
|
||||
next_state = WDATA;
|
||||
end
|
||||
end
|
||||
RDATA : begin
|
||||
if (S_AXI_rready) begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
end
|
||||
WDATA : begin
|
||||
if (S_AXI_bready) begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
logic [31:0] raddr_reg,waddr_reg;
|
||||
logic doing_write;
|
||||
assign doing_write = (S_AXI_wvalid && (state==WDATA)) ? 1 : 0;
|
||||
assign S_AXI_arready = (state == RADDR) ? 1 : 0;
|
||||
assign S_AXI_rvalid = (state == RDATA) ? 1 : 0;
|
||||
assign S_AXI_awready = (state == WADDR) ? 1 : 0;
|
||||
assign S_AXI_wready = (state == WDATA) ? 1 : 0;
|
||||
assign S_AXI_bvalid = (state == WDATA) ? 1 : 0;
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
raddr_reg <= 0;
|
||||
waddr_reg <= 0;
|
||||
end
|
||||
else begin
|
||||
if(S_AXI_arvalid) begin
|
||||
raddr_reg <= S_AXI_araddr;
|
||||
end
|
||||
if(S_AXI_awvalid) begin
|
||||
waddr_reg <= S_AXI_awaddr;
|
||||
end
|
||||
end
|
||||
end
|
||||
//Read data
|
||||
always_ff @(posedge clk) begin
|
||||
if (~axi_rvalid) begin
|
||||
case ({axi_araddr[15:2], 2'b00}) inside
|
||||
[MSIP_BASE:MSIP_BASE+4*CORES_MINUS_ONE] : axi_rdata <= {31'b0, msip[NUM_CORES == 1 ? '0 : axi_araddr[2+:CORE_W]]};
|
||||
[MTIME_BASE:MTIME_BASE+4] : axi_rdata <= mtime_packed[axi_araddr[2]];
|
||||
[MTIMECMP_BASE:MTIMECMP_BASE+8*CORES_MINUS_ONE] : axi_rdata <= mtimecmp[NUM_CORES == 1 ? '0 : axi_araddr[3+:CORE_W]][axi_araddr[2]];
|
||||
default : axi_rdata <= '0;
|
||||
endcase
|
||||
end
|
||||
case ({raddr_reg[15:2], 2'b00}) inside
|
||||
[MSIP_BASE:MSIP_BASE+4*CORES_MINUS_ONE] : S_AXI_rdata <= {31'b0, msip[NUM_CORES == 1 ? '0 : raddr_reg[2+:CORE_W]]};
|
||||
[MTIME_BASE:MTIME_BASE+4] : S_AXI_rdata <= mtime_packed[raddr_reg[2]];
|
||||
[MTIMECMP_BASE:MTIMECMP_BASE+4+8*CORES_MINUS_ONE] : S_AXI_rdata <= mtimecmp[NUM_CORES == 1 ? '0 : raddr_reg[3+:CORE_W]][raddr_reg[2]];
|
||||
default : S_AXI_rdata <= '0;
|
||||
endcase
|
||||
end
|
||||
|
||||
//Write data
|
||||
assign write_data = axi_wdata;
|
||||
assign write_upper = axi_awaddr[2];
|
||||
assign write_msip_core = NUM_CORES == 1 ? '0 : axi_awaddr[2+:CORE_W];
|
||||
assign write_mtimecmp_core = NUM_CORES == 1 ? '0 : axi_awaddr[3+:CORE_W];
|
||||
assign write_data = S_AXI_wdata;
|
||||
assign write_upper = waddr_reg[2];
|
||||
assign write_msip_core = NUM_CORES == 1 ? '0 : waddr_reg[2+:CORE_W];
|
||||
assign write_mtimecmp_core = NUM_CORES == 1 ? '0 : waddr_reg[3+:CORE_W];
|
||||
|
||||
always_comb begin
|
||||
write_msip = 0;
|
||||
write_mtime = 0;
|
||||
write_mtimecmp = 0;
|
||||
case ({axi_awaddr[15:2], 2'b00}) inside
|
||||
case ({waddr_reg[15:2], 2'b00}) inside
|
||||
[MSIP_BASE:MSIP_BASE+4*CORES_MINUS_ONE] : write_msip = doing_write;
|
||||
[MTIME_BASE:MTIME_BASE+4] : write_mtime = doing_write;
|
||||
[MTIMECMP_BASE:MTIMECMP_BASE+4+8*CORES_MINUS_ONE] : write_mtimecmp = doing_write;
|
||||
|
@ -184,11 +237,11 @@ module clint_wrapper
|
|||
end
|
||||
|
||||
//Not in use
|
||||
assign axi_awready = 0;
|
||||
assign axi_wready = 0;
|
||||
assign axi_bvalid = 0;
|
||||
assign axi_arready = 0;
|
||||
assign axi_rvalid = 0;
|
||||
assign S_AXI_awready = 0;
|
||||
assign S_AXI_wready = 0;
|
||||
assign S_AXI_bvalid = 0;
|
||||
assign S_AXI_arready = 0;
|
||||
assign S_AXI_rvalid = 0;
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
endmodule
|
|
@ -49,20 +49,20 @@ module plic_wrapper
|
|||
output logic wb_ack,
|
||||
|
||||
//Compliant AXI Lite interface; does not include optional awprot, wstrb, bresp, arprot, and rresp
|
||||
input logic axi_awvalid,
|
||||
input logic[25:2] axi_awaddr,
|
||||
output logic axi_awready,
|
||||
input logic axi_wvalid,
|
||||
input logic[31:0] axi_wdata,
|
||||
output logic axi_wready,
|
||||
output logic axi_bvalid,
|
||||
input logic axi_bready,
|
||||
input logic axi_arvalid,
|
||||
input logic[25:2] axi_araddr,
|
||||
output logic axi_arready,
|
||||
output logic axi_rvalid,
|
||||
output logic[31:0] axi_rdata,
|
||||
input logic axi_rready
|
||||
input logic S_AXI_awvalid,
|
||||
input logic[31:0] S_AXI_awaddr,
|
||||
output logic S_AXI_awready,
|
||||
input logic S_AXI_wvalid,
|
||||
input logic[31:0] S_AXI_wdata,
|
||||
output logic S_AXI_wready,
|
||||
output logic S_AXI_bvalid,
|
||||
input logic S_AXI_bready,
|
||||
input logic S_AXI_arvalid,
|
||||
input logic[31:0] S_AXI_araddr,
|
||||
output logic S_AXI_arready,
|
||||
output logic S_AXI_rvalid,
|
||||
output logic[31:0] S_AXI_rdata,
|
||||
input logic S_AXI_rready
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -98,43 +98,78 @@ module plic_wrapper
|
|||
|
||||
//Interface
|
||||
generate if (AXI) begin : gen_axi_if
|
||||
//Writes are asynchronous, reads need two cycles
|
||||
//Reads take priority over writes
|
||||
logic[25:2] saved_addr;
|
||||
always_comb begin
|
||||
if (read_reg)
|
||||
addr = saved_addr;
|
||||
else if (axi_arvalid & axi_arready)
|
||||
addr = axi_araddr[25:2];
|
||||
else
|
||||
addr = axi_awaddr[25:2];
|
||||
end
|
||||
|
||||
assign axi_arready = ~read_reg & ~axi_rvalid;
|
||||
assign axi_awready = ~axi_bvalid & ~axi_arvalid & ~read_reg & axi_awvalid & axi_wvalid;
|
||||
assign axi_wready = axi_awready;
|
||||
assign write_reg = axi_awvalid & axi_awready & axi_wvalid & axi_wready;
|
||||
assign wdata = axi_wdata;
|
||||
typedef enum logic [2:0] {
|
||||
IDLE,
|
||||
RADDR,
|
||||
WADDR,
|
||||
RDATA,
|
||||
WDATA
|
||||
} state_t;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (read_reg)
|
||||
axi_rdata <= rdata;
|
||||
if (axi_arvalid & axi_arready)
|
||||
saved_addr <= axi_araddr[25:2];
|
||||
end
|
||||
state_t state, next_state;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
read_reg <= 0;
|
||||
axi_rvalid <= 0;
|
||||
axi_bvalid <= 0;
|
||||
state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
read_reg <= axi_arvalid & axi_arready;
|
||||
axi_rvalid <= axi_rvalid ? ~axi_rready : read_reg;
|
||||
axi_bvalid <= axi_bvalid ? ~axi_bready : write_reg;
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
case (state) inside
|
||||
IDLE : begin
|
||||
if (S_AXI_awvalid) begin
|
||||
next_state = WADDR;
|
||||
end
|
||||
else if (S_AXI_arvalid) begin
|
||||
next_state = RADDR;
|
||||
end
|
||||
end
|
||||
RADDR : begin
|
||||
if (S_AXI_arready) begin
|
||||
next_state = RDATA;
|
||||
end
|
||||
end
|
||||
WADDR : begin
|
||||
if (S_AXI_wvalid) begin
|
||||
next_state = WDATA;
|
||||
end
|
||||
end
|
||||
RDATA : begin
|
||||
if (S_AXI_rready) begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
end
|
||||
WDATA : begin
|
||||
if (S_AXI_bready) begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
assign S_AXI_arready = (state == RADDR) ? 1 : 0;
|
||||
assign S_AXI_rvalid = (state == RDATA) ? 1 : 0;
|
||||
assign S_AXI_awready = (state == WADDR) ? 1 : 0;
|
||||
assign S_AXI_wready = (state == WDATA) ? 1 : 0;
|
||||
assign S_AXI_bvalid = (state == WDATA) ? 1 : 0;
|
||||
|
||||
assign read_reg = ((state == RDATA) && S_AXI_rvalid) ? 1 : 0;
|
||||
assign S_AXI_rdata = rdata;
|
||||
assign write_reg = ((state == WDATA) && S_AXI_wvalid) ? 1 : 0;
|
||||
assign wdata = S_AXI_wdata;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (S_AXI_arvalid)
|
||||
addr = S_AXI_araddr[25:2];
|
||||
else if(S_AXI_awvalid)
|
||||
addr = S_AXI_awaddr[25:2];
|
||||
end
|
||||
|
||||
|
||||
|
||||
//Not in use
|
||||
assign wb_ack = 0;
|
||||
|
@ -153,11 +188,11 @@ module plic_wrapper
|
|||
end
|
||||
|
||||
//Not in use
|
||||
assign axi_awready = 0;
|
||||
assign axi_wready = 0;
|
||||
assign axi_bvalid = 0;
|
||||
assign axi_arready = 0;
|
||||
assign axi_rvalid = 0;
|
||||
assign S_AXI_awready = 0;
|
||||
assign S_AXI_wready = 0;
|
||||
assign S_AXI_bvalid = 0;
|
||||
assign S_AXI_arready = 0;
|
||||
assign S_AXI_rvalid = 0;
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -45,6 +45,7 @@ module core_arbiter
|
|||
logic[3:0][31:2] addr;
|
||||
logic[3:0][4:0] rlen;
|
||||
logic[3:0] rnw;
|
||||
logic[3:0] rmw;
|
||||
logic[1:0] port;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -55,6 +56,7 @@ module core_arbiter
|
|||
assign addr[0] = INCLUDE_DCACHE ? dcache.addr : 'x;
|
||||
assign rlen[0] = INCLUDE_DCACHE ? dcache.rlen : 'x;
|
||||
assign rnw[0] = INCLUDE_DCACHE ? dcache.rnw : 'x;
|
||||
assign rmw[0] = INCLUDE_DCACHE ? dcache.rmw : 'x;
|
||||
assign mem.wbe = dcache.wbe;
|
||||
assign mem.wdata = dcache.wdata;
|
||||
assign dcache.inv = mem.inv;
|
||||
|
@ -68,6 +70,7 @@ module core_arbiter
|
|||
assign addr[1] = INCLUDE_ICACHE ? icache.addr : 'x;
|
||||
assign rlen[1] = INCLUDE_ICACHE ? icache.rlen : 'x;
|
||||
assign rnw[1] = INCLUDE_ICACHE ? 1 : 'x;
|
||||
assign rmw[1] = 0;
|
||||
assign icache.ack = mem.ack & port == 2'b01;
|
||||
assign icache.rvalid = mem.rvalid & mem.rid == 2'b01;
|
||||
assign icache.rdata = mem.rdata;
|
||||
|
@ -76,6 +79,7 @@ module core_arbiter
|
|||
assign addr[2] = INCLUDE_MMUS ? dmmu.addr : 'x;
|
||||
assign rlen[2] = INCLUDE_MMUS ? dmmu.rlen : 'x;
|
||||
assign rnw[2] = INCLUDE_MMUS ? 1 : 'x;
|
||||
assign rmw[2] = 0;
|
||||
assign dmmu.rdata = mem.rdata;
|
||||
assign dmmu.ack = mem.ack & port == 2'b10;
|
||||
assign dmmu.rvalid = mem.rvalid & mem.rid == 2'b10;
|
||||
|
@ -84,6 +88,7 @@ module core_arbiter
|
|||
assign addr[3] = INCLUDE_MMUS ? immu.addr : 'x;
|
||||
assign rlen[3] = INCLUDE_MMUS ? immu.rlen : 'x;
|
||||
assign rnw[3] = INCLUDE_MMUS ? 1 : 'x;
|
||||
assign rmw[3] = 0;
|
||||
assign immu.rdata = mem.rdata;
|
||||
assign immu.ack = mem.ack & port == 2'b11;
|
||||
assign immu.rvalid = mem.rvalid & mem.rid == 2'b11;
|
||||
|
@ -101,6 +106,7 @@ module core_arbiter
|
|||
assign mem.addr = addr[port];
|
||||
assign mem.rlen = rlen[port];
|
||||
assign mem.rnw = rnw[port];
|
||||
assign mem.rmw = rmw[port];
|
||||
assign mem.id = port;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -411,6 +411,7 @@ module dcache_inv
|
|||
mem.request = stage1_valid;
|
||||
mem.wdata = stage1.wdata;
|
||||
mem.rnw = 0;
|
||||
mem.rmw = 0;
|
||||
stage1_tb_write = 0;
|
||||
stage1_tb_wval = 'x;
|
||||
db_wen = stage0_advance_r & hit & ~stage1.uncacheable;
|
||||
|
@ -424,6 +425,7 @@ module dcache_inv
|
|||
mem.request = stage1_valid & ~request_sent;
|
||||
mem.wdata = 'x;
|
||||
mem.rnw = 0;
|
||||
mem.rmw = 0;
|
||||
stage1_tb_write = ~stage1.uncacheable & mem.ack & (stage0_advance_r ? hit : hit_r);
|
||||
stage1_tb_wval = 0;
|
||||
db_wen = 0;
|
||||
|
@ -437,6 +439,7 @@ module dcache_inv
|
|||
mem.request = stage1_valid & ~stage0_advance_r & (stage1.uncacheable | ~hit_r) & ~request_sent;
|
||||
mem.wdata = 'x;
|
||||
mem.rnw = 1;
|
||||
mem.rmw = 0;
|
||||
stage1_tb_write = ~stage1.uncacheable & mem.ack;
|
||||
stage1_tb_wval = 1;
|
||||
db_wen = mem.rvalid & ~stage1.uncacheable;
|
||||
|
@ -450,6 +453,7 @@ module dcache_inv
|
|||
mem.request = stage1_valid & lr_valid;
|
||||
mem.wdata = stage1.wdata;
|
||||
mem.rnw = 0;
|
||||
mem.rmw = 0;
|
||||
stage1_tb_write = 0;
|
||||
stage1_tb_wval = 'x;
|
||||
db_wen = ~stage1.uncacheable & mem.ack;
|
||||
|
@ -463,6 +467,7 @@ module dcache_inv
|
|||
mem.request = rmw_mem_request;
|
||||
mem.wdata = amo_unit.rd;
|
||||
mem.rnw = rmw_mem_rnw;
|
||||
mem.rmw = 1;
|
||||
stage1_tb_write = rmw_stage1_tb_write;
|
||||
stage1_tb_wval = 1;
|
||||
db_wen = rmw_db_wen;
|
||||
|
|
|
@ -132,6 +132,7 @@ interface mem_interface;
|
|||
logic[1:0] rid;
|
||||
|
||||
logic rnw;
|
||||
logic rmw;
|
||||
logic[3:0] wbe;
|
||||
logic[31:0] wdata;
|
||||
|
||||
|
@ -143,9 +144,9 @@ interface mem_interface;
|
|||
|
||||
modport ro_master (output request, addr, rlen, input ack, rvalid, rdata);
|
||||
modport ro_slave (input request, addr, rlen, output ack, rvalid, rdata);
|
||||
modport rw_master (output request, addr, rlen, rnw, wbe, wdata, input ack, rvalid, rdata, inv, inv_addr, write_outstanding);
|
||||
modport rw_slave (input request, addr, rlen, rnw, wbe, wdata, output ack, rvalid, rdata, inv, inv_addr, write_outstanding);
|
||||
modport mem_master (output request, addr, rlen, rnw, wbe, wdata, id, input ack, rvalid, rdata, rid, inv, inv_addr, write_outstanding);
|
||||
modport mem_slave (input request, addr, rlen, rnw, wbe, wdata, id, output ack, rvalid, rdata, rid, inv, inv_addr, write_outstanding);
|
||||
modport rw_master (output request, addr, rlen, rnw, rmw, wbe, wdata, input ack, rvalid, rdata, inv, inv_addr, write_outstanding);
|
||||
modport rw_slave (input request, addr, rlen, rnw, rmw, wbe, wdata, output ack, rvalid, rdata, inv, inv_addr, write_outstanding);
|
||||
modport mem_master (output request, addr, rlen, rnw, rmw, wbe, wdata, id, input ack, rvalid, rdata, rid, inv, inv_addr, write_outstanding);
|
||||
modport mem_slave (input request, addr, rlen, rnw, rmw, wbe, wdata, id, output ack, rvalid, rdata, rid, inv, inv_addr, write_outstanding);
|
||||
|
||||
endinterface
|
||||
|
|
|
@ -28,7 +28,8 @@ module litex_wrapper
|
|||
parameter bit [31:0] RESET_VEC = 0,
|
||||
parameter bit [31:0] NON_CACHABLE_L = 32'h80000000,
|
||||
parameter bit [31:0] NON_CACHABLE_H = 32'hFFFFFFFF,
|
||||
parameter int unsigned NUM_CORES = 1
|
||||
parameter int unsigned NUM_CORES = 1,
|
||||
parameter logic AXI = 1'b1 //Else the wishbone bus is used
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
|
@ -50,7 +51,53 @@ module litex_wrapper
|
|||
output logic idbus_bte,
|
||||
input logic [31:0] idbus_dat_r,
|
||||
input logic idbus_ack,
|
||||
input logic idbus_err
|
||||
input logic idbus_err,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// AXI SIGNALS - need these to unwrap the interface for packaging //
|
||||
input logic m_axi_arready,
|
||||
output logic m_axi_arvalid,
|
||||
output logic [C_M_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
|
||||
output logic [7:0] m_axi_arlen,
|
||||
output logic [2:0] m_axi_arsize,
|
||||
output logic [1:0] m_axi_arburst,
|
||||
output logic [3:0] m_axi_arcache,
|
||||
output logic [5:0] m_axi_arid,
|
||||
|
||||
//read data
|
||||
output logic m_axi_rready,
|
||||
input logic m_axi_rvalid,
|
||||
input logic [C_M_AXI_DATA_WIDTH-1:0] m_axi_rdata,
|
||||
input logic [1:0] m_axi_rresp,
|
||||
input logic m_axi_rlast,
|
||||
input logic [5:0] m_axi_rid,
|
||||
|
||||
//Write channel
|
||||
//write address
|
||||
input logic m_axi_awready,
|
||||
output logic m_axi_awvalid,
|
||||
output logic [C_M_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
|
||||
output logic [7:0] m_axi_awlen,
|
||||
output logic [2:0] m_axi_awsize,
|
||||
output logic [1:0] m_axi_awburst,
|
||||
output logic [3:0] m_axi_awcache,
|
||||
output logic [5:0] m_axi_awid,
|
||||
|
||||
//write data
|
||||
input logic m_axi_wready,
|
||||
output logic m_axi_wvalid,
|
||||
output logic [C_M_AXI_DATA_WIDTH-1:0] m_axi_wdata,
|
||||
output logic [(C_M_AXI_DATA_WIDTH/8)-1:0] m_axi_wstrb,
|
||||
output logic m_axi_wlast,
|
||||
|
||||
//write response
|
||||
output logic m_axi_bready,
|
||||
input logic m_axi_bvalid,
|
||||
input logic [1:0] m_axi_bresp,
|
||||
input logic [5:0] m_axi_bid
|
||||
);
|
||||
|
||||
localparam wb_group_config_t STANDARD_WB_GROUP_CONFIG = '{
|
||||
|
@ -76,13 +123,7 @@ module litex_wrapper
|
|||
mem_interface mem[NUM_CORES-1:0]();
|
||||
|
||||
//Final memory interface
|
||||
wishbone_interface idwishbone();
|
||||
|
||||
//Mux requests from one or more cores onto the wishbone bus
|
||||
wishbone_adapter #(.NUM_CORES(NUM_CORES)) wb_adapter (
|
||||
.mems(mem),
|
||||
.wishbone(idwishbone),
|
||||
.*);
|
||||
|
||||
generate for (genvar i = 0; i < NUM_CORES; i++) begin : gen_cores
|
||||
localparam cpu_config_t STANDARD_CONFIG_I = '{
|
||||
|
@ -213,18 +254,86 @@ module litex_wrapper
|
|||
.s_interrupt(s_interrupt[i]),
|
||||
.m_interrupt(m_interrupt[i]),
|
||||
.*);
|
||||
|
||||
|
||||
end endgenerate
|
||||
|
||||
assign idbus_adr = idwishbone.adr;
|
||||
assign idbus_dat_w = idwishbone.dat_w;
|
||||
assign idbus_sel = idwishbone.sel;
|
||||
assign idbus_cyc = idwishbone.cyc;
|
||||
assign idbus_stb = idwishbone.stb;
|
||||
assign idbus_we = idwishbone.we;
|
||||
assign idbus_cti = idwishbone.cti;
|
||||
assign idbus_bte = idwishbone.bte;
|
||||
assign idwishbone.dat_r = idbus_dat_r;
|
||||
assign idwishbone.ack = idbus_ack;
|
||||
assign idwishbone.err = idbus_err;
|
||||
|
||||
|
||||
|
||||
generate if (AXI) begin : gen_axi_if
|
||||
axi_interface m_axi_l2();
|
||||
|
||||
axi_adapter #(.NUM_CORES(NUM_CORES)) wb_adapter (
|
||||
.mems(mem),
|
||||
.axi(m_axi_l2),
|
||||
.*);
|
||||
|
||||
|
||||
assign m_axi_l2.arready = m_axi_arready ;
|
||||
assign m_axi_arvalid = m_axi_l2.arvalid;
|
||||
assign m_axi_araddr = m_axi_l2.araddr;
|
||||
assign m_axi_arlen = m_axi_l2.arlen;
|
||||
assign m_axi_arsize = m_axi_l2.arsize;
|
||||
assign m_axi_arburst = m_axi_l2.arburst;
|
||||
assign m_axi_arcache = m_axi_l2.arcache;
|
||||
assign m_axi_arid = m_axi_l2.arid;
|
||||
|
||||
assign m_axi_rready = m_axi_l2.rready;
|
||||
assign m_axi_l2.rvalid = m_axi_rvalid;
|
||||
assign m_axi_l2.rdata = m_axi_rdata;
|
||||
assign m_axi_l2.rresp = m_axi_rresp;
|
||||
assign m_axi_l2.rlast = m_axi_rlast;
|
||||
assign m_axi_l2.rid = m_axi_rid;
|
||||
|
||||
assign m_axi_l2.awready = m_axi_awready;
|
||||
assign m_axi_awvalid = m_axi_l2.awvalid;
|
||||
assign m_axi_awaddr = m_axi_l2.awaddr;
|
||||
assign m_axi_awlen = m_axi_l2.awlen;
|
||||
assign m_axi_awsize = m_axi_l2.awsize;
|
||||
assign m_axi_awburst = m_axi_l2.awburst;
|
||||
assign m_axi_awcache = m_axi_l2.awcache;
|
||||
assign m_axi_awid = m_axi_l2.awid;
|
||||
|
||||
//write data
|
||||
assign m_axi_l2.wready = m_axi_wready;
|
||||
assign m_axi_wvalid = m_axi_l2.wvalid;
|
||||
assign m_axi_wdata = m_axi_l2.wdata;
|
||||
assign m_axi_wstrb = m_axi_l2.wstrb;
|
||||
assign m_axi_wlast = m_axi_l2.wlast;
|
||||
|
||||
//write response
|
||||
assign m_axi_bready = m_axi_l2.bready;
|
||||
assign m_axi_l2.bvalid = m_axi_bvalid;
|
||||
assign m_axi_l2.bresp = m_axi_bresp;
|
||||
assign m_axi_l2.bid = m_axi_bid;
|
||||
|
||||
|
||||
end else begin : gen_wishbone_if
|
||||
|
||||
wishbone_interface idwishbone();
|
||||
|
||||
//Mux requests from one or more cores onto the wishbone bus
|
||||
wishbone_adapter #(.NUM_CORES(NUM_CORES)) wb_adapter (
|
||||
.mems(mem),
|
||||
.wishbone(idwishbone),
|
||||
.*);
|
||||
|
||||
assign idbus_adr = idwishbone.adr;
|
||||
assign idbus_dat_w = idwishbone.dat_w;
|
||||
assign idbus_sel = idwishbone.sel;
|
||||
assign idbus_cyc = idwishbone.cyc;
|
||||
assign idbus_stb = idwishbone.stb;
|
||||
assign idbus_we = idwishbone.we;
|
||||
assign idbus_cti = idwishbone.cti;
|
||||
assign idbus_bte = idwishbone.bte;
|
||||
assign idwishbone.dat_r = idbus_dat_r;
|
||||
assign idwishbone.ack = idbus_ack;
|
||||
assign idwishbone.err = idbus_err;
|
||||
end endgenerate
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue