Added LiteX support

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2022-05-16 13:36:31 -04:00
parent 2290527612
commit b2e425abed
3 changed files with 473 additions and 1 deletions

View file

@ -42,7 +42,7 @@ module wishbone_master
always_ff @ (posedge clk) begin
if (ls.new_request) begin
wishbone.adr <= ls.addr[29:0];
wishbone.adr <= ls.addr[31:2];
wishbone.sel <= ls.we ? ls.be : '1;
wishbone.we <= ls.we;
wishbone.dat_w <= ls.data_in;

View file

@ -0,0 +1,120 @@
/*
* Copyright © 2022 Eric Matthews, Lesley Shannon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial code developed under the supervision of Dr. Lesley Shannon,
* Reconfigurable Computing Lab, Simon Fraser University.
*
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
module l1_to_wishbone
import cva5_config::*;
import riscv_types::*;
import cva5_types::*;
import l2_config_and_types::*;
(
input logic clk,
input logic rst,
l2_requester_interface.slave cpu,
wishbone_interface.master wishbone
);
localparam MAX_REQUESTS = 32;
fifo_interface #(.DATA_WIDTH($bits(l2_request_t))) request_fifo ();
fifo_interface #(.DATA_WIDTH(32)) data_fifo ();
l2_request_t request_in;
l2_request_t request;
logic request_complete;
////////////////////////////////////////////////////
//Implementation
assign cpu.request_full = request_fifo.full;
assign cpu.data_full = data_fifo.full;
//Repack input attributes
assign request_in.addr = cpu.addr;
assign request_in.be = cpu.be;
assign request_in.rnw = cpu.rnw;
assign request_in.is_amo = cpu.is_amo;
assign request_in.amo_type_or_burst_size = cpu.amo_type_or_burst_size;
assign request_in.sub_id = cpu.sub_id;
assign request_fifo.push = cpu.request_push;
assign request_fifo.potential_push = cpu.request_push;
assign request_fifo.pop = request_complete;
assign request_fifo.data_in = request_in;
assign request = request_fifo.data_out;
assign data_fifo.push = cpu.wr_data_push;
assign data_fifo.potential_push = cpu.wr_data_push;
assign data_fifo.pop = wishbone.we & wishbone.ack;
assign data_fifo.data_in = cpu.wr_data;
cva5_fifo #(.DATA_WIDTH($bits(l2_request_t)), .FIFO_DEPTH(MAX_REQUESTS))
request_fifo_block (
.clk (clk),
.rst (rst),
.fifo (request_fifo)
);
cva5_fifo #(.DATA_WIDTH(32), .FIFO_DEPTH(MAX_REQUESTS))
data_fifo_block (
.clk (clk),
.rst (rst),
.fifo (data_fifo)
);
////////////////////////////////////////////////////
//Wishbone
logic [4:0] burst_size;
logic [4:0] burst_count;
assign wishbone.cti = 0;
assign wishbone.bte = 0;
always_ff @ (posedge clk) begin
if (rst | request_fifo.pop)
burst_count <= 0;
else
burst_count <= burst_count + 5'(wishbone.ack);
end
assign burst_size = request.amo_type_or_burst_size;
assign request_complete = wishbone.ack & (burst_count == burst_size);
assign wishbone.adr[29:5] = request.addr[29:5];
assign wishbone.adr[4:0] = (request.addr[4:0] & ~burst_size) | (burst_count & burst_size);
assign wishbone.sel = request.rnw ? '1 : request.be;
assign wishbone.we = ~request.rnw;
assign wishbone.dat_w = data_fifo.data_out;
assign wishbone.stb = request_fifo.valid;
assign wishbone.cyc = request_fifo.valid;
////////////////////////////////////////////////////
//Return Path
//L1 always acks data, no need for rd_data_ack
always_ff @ (posedge clk) begin
cpu.rd_data <= wishbone.dat_r;
cpu.rd_data_valid <= request.rnw & wishbone.ack;
cpu.rd_sub_id <= request.sub_id;
end
endmodule

352
examples/litex/litex_wrapper.sv Executable file
View file

@ -0,0 +1,352 @@
/*
* Copyright © 2022 Eric Matthews, Lesley Shannon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial code developed under the supervision of Dr. Lesley Shannon,
* Reconfigurable Computing Lab, Simon Fraser University.
*
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
module litex_wrapper
import cva5_config::*;
import cva5_types::*;
import l2_config_and_types::*;
#(
parameter LITEX_VARIANT = 0,
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
)
(
input logic clk,
input logic rst,
input logic [15:0] litex_interrupt,
output logic [29:0] ibus_adr,
output logic [31:0] ibus_dat_w,
output logic [3:0] ibus_sel,
output logic ibus_cyc,
output logic ibus_stb,
output logic ibus_we,
output logic ibus_cti,
output logic ibus_bte,
input logic [31:0] ibus_dat_r,
input logic ibus_ack,
input logic ibus_err,
output logic [29:0] dbus_adr,
output logic [31:0] dbus_dat_w,
output logic [3:0] dbus_sel,
output logic dbus_cyc,
output logic dbus_stb,
output logic dbus_we,
output logic dbus_cti,
output logic dbus_bte,
input logic [31:0] dbus_dat_r,
input logic dbus_ack,
input logic dbus_err,
output logic [29:0] idbus_adr,
output logic [31:0] idbus_dat_w,
output logic [3:0] idbus_sel,
output logic idbus_cyc,
output logic idbus_stb,
output logic idbus_we,
output logic idbus_cti,
output logic idbus_bte,
input logic [31:0] idbus_dat_r,
input logic idbus_ack,
input logic idbus_err
);
localparam cpu_config_t MINIMAL_CONFIG = '{
//ISA options
INCLUDE_M_MODE : 0,
INCLUDE_S_MODE : 0,
INCLUDE_U_MODE : 0,
INCLUDE_MUL : 0,
INCLUDE_DIV : 0,
INCLUDE_IFENCE : 0,
INCLUDE_CSRS : 0,
INCLUDE_AMO : 0,
//CSR constants
CSRS : '{
MACHINE_IMPLEMENTATION_ID : 0,
CPU_ID : 0,
RESET_VEC : RESET_VEC,
RESET_MTVEC : 32'h00000000,
NON_STANDARD_OPTIONS : '{
COUNTER_W : 33,
MCYCLE_WRITEABLE : 0,
MINSTR_WRITEABLE : 0,
MTVEC_WRITEABLE : 0,
INCLUDE_MSCRATCH : 0,
INCLUDE_MCAUSE : 0,
INCLUDE_MTVAL : 0
}
},
//Memory Options
SQ_DEPTH : 2,
INCLUDE_ICACHE : 0,
ICACHE_ADDR : '{
L: 32'h40000000,
H: 32'h4FFFFFFF
},
ICACHE : '{
LINES : 512,
LINE_W : 4,
WAYS : 2,
USE_EXTERNAL_INVALIDATIONS : 0,
USE_NON_CACHEABLE : 0,
NON_CACHEABLE : '{
L: 32'h00000000,
H: 32'h00000000
}
},
ITLB : '{
WAYS : 2,
DEPTH : 64
},
INCLUDE_DCACHE : 0,
DCACHE_ADDR : '{
L: 32'h40000000,
H: 32'h4FFFFFFF
},
DCACHE : '{
LINES : 512,
LINE_W : 4,
WAYS : 2,
USE_EXTERNAL_INVALIDATIONS : 0,
USE_NON_CACHEABLE : 0,
NON_CACHEABLE : '{
L: 32'h00000000,
H: 32'h00000000
}
},
DTLB : '{
WAYS : 2,
DEPTH : 64
},
INCLUDE_ILOCAL_MEM : 0,
ILOCAL_MEM_ADDR : '{
L : 32'h80000000,
H : 32'h8FFFFFFF
},
INCLUDE_DLOCAL_MEM : 0,
DLOCAL_MEM_ADDR : '{
L : 32'h80000000,
H : 32'h8FFFFFFF
},
INCLUDE_IBUS : 1,
IBUS_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
INCLUDE_PERIPHERAL_BUS : 1,
PERIPHERAL_BUS_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
PERIPHERAL_BUS_TYPE : WISHBONE_BUS,
//Branch Predictor Options
INCLUDE_BRANCH_PREDICTOR : 0,
BP : '{
WAYS : 2,
ENTRIES : 512,
RAS_ENTRIES : 8
},
//Writeback Options
NUM_WB_GROUPS : 2
};
localparam cpu_config_t STANDARD_CONFIG = '{
//ISA options
INCLUDE_M_MODE : 1,
INCLUDE_S_MODE : 0,
INCLUDE_U_MODE : 0,
INCLUDE_MUL : 1,
INCLUDE_DIV : 1,
INCLUDE_IFENCE : 0,
INCLUDE_CSRS : 1,
INCLUDE_AMO : 0,
//CSR constants
CSRS : '{
MACHINE_IMPLEMENTATION_ID : 0,
CPU_ID : 0,
RESET_VEC : RESET_VEC,
RESET_MTVEC : 32'h00000000,
NON_STANDARD_OPTIONS : '{
COUNTER_W : 33,
MCYCLE_WRITEABLE : 0,
MINSTR_WRITEABLE : 0,
MTVEC_WRITEABLE : 1,
INCLUDE_MSCRATCH : 0,
INCLUDE_MCAUSE : 1,
INCLUDE_MTVAL : 1
}
},
//Memory Options
SQ_DEPTH : 4,
INCLUDE_ICACHE : 1,
ICACHE_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
ICACHE : '{
LINES : 512,
LINE_W : 4,
WAYS : 2,
USE_EXTERNAL_INVALIDATIONS : 0,
USE_NON_CACHEABLE : 0,
NON_CACHEABLE : '{
L: NON_CACHABLE_L,
H: NON_CACHABLE_H
}
},
ITLB : '{
WAYS : 2,
DEPTH : 64
},
INCLUDE_DCACHE : 1,
DCACHE_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
DCACHE : '{
LINES : 512,
LINE_W : 4,
WAYS : 2,
USE_EXTERNAL_INVALIDATIONS : 0,
USE_NON_CACHEABLE : 1,
NON_CACHEABLE : '{
L: NON_CACHABLE_L,
H: NON_CACHABLE_H
}
},
DTLB : '{
WAYS : 2,
DEPTH : 64
},
INCLUDE_ILOCAL_MEM : 0,
ILOCAL_MEM_ADDR : '{
L : 32'h80000000,
H : 32'h8FFFFFFF
},
INCLUDE_DLOCAL_MEM : 0,
DLOCAL_MEM_ADDR : '{
L : 32'h80000000,
H : 32'h8FFFFFFF
},
INCLUDE_IBUS : 0,
IBUS_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
INCLUDE_PERIPHERAL_BUS : 0,
PERIPHERAL_BUS_ADDR : '{
L : 32'h00000000,
H : 32'hFFFFFFFF
},
PERIPHERAL_BUS_TYPE : WISHBONE_BUS,
//Branch Predictor Options
INCLUDE_BRANCH_PREDICTOR : 1,
BP : '{
WAYS : 2,
ENTRIES : 512,
RAS_ENTRIES : 8
},
//Writeback Options
NUM_WB_GROUPS : 2
};
function cpu_config_t config_select (input integer variant);
case (variant)
0 : config_select = MINIMAL_CONFIG;
1 : config_select = STANDARD_CONFIG;
default : config_select = STANDARD_CONFIG;
endcase
endfunction
localparam cpu_config_t LITEX_CONFIG = config_select(LITEX_VARIANT);
//Unused interfaces
axi_interface m_axi();
avalon_interface m_avalon();
local_memory_interface instruction_bram();
local_memory_interface data_bram();
trace_outputs_t tr;
interrupt_t s_interrupt;
//L2 to Wishbone
l2_requester_interface l2();
//Wishbone interfaces
wishbone_interface dwishbone();
wishbone_interface iwishbone();
wishbone_interface idwishbone();
//Timer and External interrupts
interrupt_t m_interrupt;
assign m_interrupt.software = 0;
assign m_interrupt.timer = litex_interrupt[1];
assign m_interrupt.external = litex_interrupt[0];
cva5 #(.CONFIG(LITEX_CONFIG)) cpu(.*);
generate if (LITEX_VARIANT != 0) begin : l1_arb_gen
l1_to_wishbone arb(.*, .cpu(l2), .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 else begin
assign ibus_adr = iwishbone.adr;
assign ibus_dat_w = iwishbone.dat_w;
assign ibus_sel = iwishbone.sel;
assign ibus_cyc = iwishbone.cyc;
assign ibus_stb = iwishbone.stb;
assign ibus_we = iwishbone.we;
assign ibus_cti = iwishbone.cti;
assign ibus_bte = iwishbone.bte;
assign iwishbone.dat_r = ibus_dat_r;
assign iwishbone.ack = ibus_ack;
assign iwishbone.err = ibus_err;
assign dbus_adr = dwishbone.adr;
assign dbus_dat_w = dwishbone.dat_w;
assign dbus_sel = dwishbone.sel;
assign dbus_cyc = dwishbone.cyc;
assign dbus_stb = dwishbone.stb;
assign dbus_we = dwishbone.we;
assign dbus_cti = dwishbone.cti;
assign dbus_bte = dwishbone.bte;
assign dwishbone.dat_r = dbus_dat_r;
assign dwishbone.ack = dbus_ack;
assign dwishbone.err = dbus_err;
end endgenerate
endmodule