mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-22 13:07:33 -04:00
Add nexys 7 example
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
3e691efb37
commit
b5f792048b
7 changed files with 1494 additions and 1 deletions
164
examples/nexys/l1_to_axi.sv
Normal file
164
examples/nexys/l1_to_axi.sv
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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_axi
|
||||
|
||||
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,
|
||||
axi_interface.master axi
|
||||
);
|
||||
|
||||
localparam MAX_REQUESTS = 16;
|
||||
|
||||
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 write_request;
|
||||
|
||||
logic read_pop;
|
||||
logic write_pop;
|
||||
|
||||
logic aw_complete;
|
||||
logic w_complete;
|
||||
logic aw_complete_r;
|
||||
logic w_complete_r;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//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 = read_pop | write_pop;
|
||||
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 = write_pop;
|
||||
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)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//AXI
|
||||
localparam MAX_WRITE_IN_FLIGHT = 64;
|
||||
logic [$clog2(MAX_WRITE_IN_FLIGHT)-1:0] write_in_flight_count;
|
||||
logic [$clog2(MAX_WRITE_IN_FLIGHT)-1:0] write_in_flight_count_next;
|
||||
|
||||
logic [4:0] burst_size;
|
||||
assign burst_size = request.amo_type_or_burst_size;
|
||||
|
||||
//Read Channel
|
||||
assign axi.arlen = 8'(burst_size);
|
||||
assign axi.arburst = (burst_size !=0) ? 2'b01 : '0;// INCR
|
||||
assign axi.rready = 1; //always ready to receive data
|
||||
assign axi.arsize = 3'b010;//4 bytes
|
||||
assign axi.arcache = 4'b0011; //Normal Non-cacheable Non-bufferable
|
||||
assign axi.arid = 6'(request.sub_id);
|
||||
|
||||
assign axi.araddr = {request.addr, 2'b00} & {25'h1FFFFFF, ~burst_size, 2'b00};
|
||||
assign axi.arvalid = request.rnw & request_fifo.valid & ((request.sub_id[1:0] != L1_DCACHE_ID) | ((request.sub_id[1:0] == L1_DCACHE_ID) & (write_in_flight_count == 0)));
|
||||
|
||||
assign read_pop = axi.arvalid & axi.arready;
|
||||
|
||||
//Write Channel
|
||||
assign axi.awlen = '0;
|
||||
assign axi.awburst = '0;//2'b01;// INCR
|
||||
assign axi.awsize = 3'b010;//4 bytes
|
||||
assign axi.bready = 1;
|
||||
assign axi.awcache = 4'b0011;//Normal Non-cacheable Non-bufferable
|
||||
assign axi.awaddr = {request.addr, 2'b00};
|
||||
assign axi.awid = 6'(request.sub_id);
|
||||
|
||||
assign write_request = (~request.rnw) & request_fifo.valid & data_fifo.valid;
|
||||
assign axi.awvalid = write_request & ~aw_complete_r;
|
||||
|
||||
assign axi.wdata = data_fifo.data_out;
|
||||
assign axi.wstrb = request.be;
|
||||
assign axi.wvalid = write_request & ~w_complete_r;
|
||||
assign axi.wlast = axi.wvalid;
|
||||
|
||||
assign aw_complete = axi.awvalid & axi.awready;
|
||||
assign w_complete = axi.wvalid & axi.wready;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
aw_complete_r <= 0;
|
||||
else
|
||||
aw_complete_r <= (aw_complete_r | aw_complete) & ~write_pop;
|
||||
end
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
w_complete_r <= 0;
|
||||
else
|
||||
w_complete_r <= (w_complete_r | w_complete) & ~write_pop;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
write_in_flight_count <= 0;
|
||||
else
|
||||
write_in_flight_count <= write_in_flight_count + $clog2(MAX_WRITE_IN_FLIGHT)'({(aw_complete | aw_complete_r) & (w_complete | w_complete_r)}) - $clog2(MAX_WRITE_IN_FLIGHT)'(axi.bvalid);
|
||||
end
|
||||
|
||||
assign write_pop = (aw_complete | aw_complete_r) & (w_complete | w_complete_r);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Return Path
|
||||
//L1 always acks data, no need for rd_data_ack
|
||||
always_ff @ (posedge clk) begin
|
||||
cpu.rd_data <= axi.rdata;
|
||||
cpu.rd_data_valid <= axi.rvalid;
|
||||
cpu.rd_sub_id <= axi.rid[L2_SUB_ID_W-1:0];
|
||||
end
|
||||
endmodule
|
485
examples/nexys/nexys_sim.sv
Normal file
485
examples/nexys/nexys_sim.sv
Normal file
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
* Copyright © 2017 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 cva5_sim
|
||||
|
||||
import cva5_config::*;
|
||||
import l2_config_and_types::*;
|
||||
import riscv_types::*;
|
||||
import cva5_types::*;
|
||||
|
||||
# (
|
||||
parameter MEMORY_FILE = "/home/ematthew/Research/RISCV/software/riscv-tools/riscv-tests/benchmarks/dhrystone.riscv.hw_init" //change this to appropriate location "/home/ematthew/Downloads/dhrystone.riscv.sim_init"
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
||||
//DDR AXI
|
||||
output logic [31:0]ddr_axi_araddr,
|
||||
output logic [1:0]ddr_axi_arburst,
|
||||
output logic [3:0]ddr_axi_arcache,
|
||||
output logic [5:0]ddr_axi_arid,
|
||||
output logic [7:0]ddr_axi_arlen,
|
||||
output logic [0:0]ddr_axi_arlock,
|
||||
output logic [2:0]ddr_axi_arprot,
|
||||
output logic [3:0]ddr_axi_arqos,
|
||||
input logic ddr_axi_arready,
|
||||
output logic [3:0]ddr_axi_arregion,
|
||||
output logic [2:0]ddr_axi_arsize,
|
||||
output logic ddr_axi_arvalid,
|
||||
output logic [31:0]ddr_axi_awaddr,
|
||||
output logic [1:0]ddr_axi_awburst,
|
||||
output logic [3:0]ddr_axi_awcache,
|
||||
output logic [5:0]ddr_axi_awid,
|
||||
output logic [7:0]ddr_axi_awlen,
|
||||
output logic [0:0]ddr_axi_awlock,
|
||||
output logic [2:0]ddr_axi_awprot,
|
||||
output logic [3:0]ddr_axi_awqos,
|
||||
input logic ddr_axi_awready,
|
||||
output logic [3:0]ddr_axi_awregion,
|
||||
output logic [2:0]ddr_axi_awsize,
|
||||
output logic ddr_axi_awvalid,
|
||||
output logic [5:0]ddr_axi_bid,
|
||||
output logic ddr_axi_bready,
|
||||
input logic [1:0]ddr_axi_bresp,
|
||||
input logic ddr_axi_bvalid,
|
||||
input logic [31:0]ddr_axi_rdata,
|
||||
input logic [5:0]ddr_axi_rid,
|
||||
input logic ddr_axi_rlast,
|
||||
output logic ddr_axi_rready,
|
||||
input logic [1:0]ddr_axi_rresp,
|
||||
input logic ddr_axi_rvalid,
|
||||
output logic [31:0]ddr_axi_wdata,
|
||||
output logic ddr_axi_wlast,
|
||||
input logic ddr_axi_wready,
|
||||
output logic [3:0]ddr_axi_wstrb,
|
||||
output logic ddr_axi_wvalid,
|
||||
output logic [5:0]ddr_axi_wid,
|
||||
|
||||
//Local Memory
|
||||
output logic [29:0] instruction_bram_addr,
|
||||
output logic instruction_bram_en,
|
||||
output logic [3:0] instruction_bram_be,
|
||||
output logic [31:0] instruction_bram_data_in,
|
||||
input logic [31:0] instruction_bram_data_out,
|
||||
|
||||
output logic [29:0] data_bram_addr,
|
||||
output logic data_bram_en,
|
||||
output logic [3:0] data_bram_be,
|
||||
output logic [31:0] data_bram_data_in,
|
||||
input logic [31:0] data_bram_data_out,
|
||||
|
||||
//Used by verilator
|
||||
output logic write_uart,
|
||||
output logic [7:0] uart_byte,
|
||||
|
||||
//Trace Interface
|
||||
output integer NUM_RETIRE_PORTS,
|
||||
output logic [31:0] retire_ports_instruction [RETIRE_PORTS],
|
||||
output logic [31:0] retire_ports_pc [RETIRE_PORTS],
|
||||
output logic retire_ports_valid [RETIRE_PORTS],
|
||||
output logic store_queue_empty
|
||||
);
|
||||
|
||||
localparam cpu_config_t NEXYS_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 : 32'h80000000,
|
||||
RESET_MTVEC : 32'h80000000,
|
||||
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'h80000000,
|
||||
H : 32'h87FFFFFF
|
||||
},
|
||||
ICACHE : '{
|
||||
LINES : 512,
|
||||
LINE_W : 4,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
NON_CACHEABLE : '{
|
||||
L : 32'h88000000,
|
||||
H : 32'h8FFFFFFF
|
||||
}
|
||||
},
|
||||
ITLB : '{
|
||||
WAYS : 2,
|
||||
DEPTH : 64
|
||||
},
|
||||
INCLUDE_DCACHE : 1,
|
||||
DCACHE_ADDR : '{
|
||||
L : 32'h80000000,
|
||||
H : 32'h8FFFFFFF
|
||||
},
|
||||
DCACHE : '{
|
||||
LINES : 1024,
|
||||
LINE_W : 4,
|
||||
WAYS : 1,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 1,
|
||||
NON_CACHEABLE : '{
|
||||
L : 32'h88000000,
|
||||
H : 32'h8FFFFFFF
|
||||
}
|
||||
},
|
||||
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'h88000000,
|
||||
H : 32'h8FFFFFFF
|
||||
},
|
||||
PERIPHERAL_BUS_TYPE : AXI_BUS,
|
||||
//Branch Predictor Options
|
||||
INCLUDE_BRANCH_PREDICTOR : 1,
|
||||
BP : '{
|
||||
WAYS : 2,
|
||||
ENTRIES : 512,
|
||||
RAS_ENTRIES : 8
|
||||
},
|
||||
//Writeback Options
|
||||
NUM_WB_GROUPS : 2
|
||||
};
|
||||
|
||||
parameter SCRATCH_MEM_KB = 128;
|
||||
parameter MEM_LINES = (SCRATCH_MEM_KB*1024)/4;
|
||||
parameter UART_ADDR = 32'h88001000;
|
||||
parameter UART_ADDR_LINE_STATUS = 32'h88001014;
|
||||
|
||||
interrupt_t s_interrupt;
|
||||
interrupt_t m_interrupt;
|
||||
|
||||
assign s_interrupt = '{default: 0};
|
||||
assign m_interrupt = '{default: 0};
|
||||
|
||||
local_memory_interface instruction_bram();
|
||||
local_memory_interface data_bram();
|
||||
axi_interface m_axi ();
|
||||
avalon_interface m_avalon();
|
||||
wishbone_interface dwishbone();
|
||||
wishbone_interface iwishbone();
|
||||
|
||||
//L2 and AXI
|
||||
axi_interface axi ();
|
||||
l2_requester_interface l2 ();
|
||||
|
||||
assign instruction_bram_addr = instruction_bram.addr;
|
||||
assign instruction_bram_en = instruction_bram.en;
|
||||
assign instruction_bram_be = instruction_bram.be;
|
||||
assign instruction_bram_data_in = instruction_bram.data_in;
|
||||
assign instruction_bram.data_out = instruction_bram_data_out;
|
||||
|
||||
assign data_bram_addr = data_bram.addr;
|
||||
assign data_bram_en = data_bram.en;
|
||||
assign data_bram_be = data_bram.be;
|
||||
assign data_bram_data_in = data_bram.data_in;
|
||||
assign data_bram.data_out = data_bram_data_out;
|
||||
|
||||
l1_to_axi arb(.*, .cpu(l2), .axi(axi));
|
||||
cva5 #(.CONFIG(NEXYS_CONFIG)) cpu(.*);
|
||||
|
||||
initial begin
|
||||
write_uart = 0;
|
||||
uart_byte = 0;
|
||||
end
|
||||
//Capture writes to UART
|
||||
always_ff @(posedge clk) begin
|
||||
write_uart <= (axi.wvalid && axi.wready && axi.awaddr == UART_ADDR);
|
||||
uart_byte <= axi.wdata[7:0];
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//DDR AXI interface
|
||||
assign ddr_axi_araddr = axi.araddr;
|
||||
assign ddr_axi_arburst = axi.arburst;
|
||||
assign ddr_axi_arcache = axi.arcache;
|
||||
assign ddr_axi_arid = axi.arid;
|
||||
assign ddr_axi_arlen = axi.arlen;
|
||||
assign axi.arready = ddr_axi_arready;
|
||||
assign ddr_axi_arsize = axi.arsize;
|
||||
assign ddr_axi_arvalid = axi.arvalid;
|
||||
|
||||
assign ddr_axi_awaddr = axi.awaddr;
|
||||
assign ddr_axi_awburst = axi.awburst;
|
||||
assign ddr_axi_awcache = axi.awcache;
|
||||
assign ddr_axi_awid = axi.awid;
|
||||
assign ddr_axi_awlen = axi.awlen;
|
||||
assign axi.awready = ddr_axi_awready;
|
||||
assign ddr_axi_awvalid = axi.awvalid;
|
||||
|
||||
assign axi.bid = ddr_axi_bid;
|
||||
assign ddr_axi_bready = axi.bready;
|
||||
assign axi.bresp = ddr_axi_bresp;
|
||||
assign axi.bvalid = ddr_axi_bvalid;
|
||||
|
||||
assign axi.rdata = ddr_axi_rdata;
|
||||
assign axi.rid = ddr_axi_rid;
|
||||
assign axi.rlast = ddr_axi_rlast;
|
||||
assign ddr_axi_rready = axi.rready;
|
||||
assign axi.rresp = ddr_axi_rresp;
|
||||
assign axi.rvalid = ddr_axi_rvalid;
|
||||
|
||||
assign ddr_axi_wdata = axi.wdata;
|
||||
assign ddr_axi_wlast = axi.wlast;
|
||||
assign axi.wready = ddr_axi_wready;
|
||||
assign ddr_axi_wstrb = axi.wstrb;
|
||||
assign ddr_axi_wvalid = axi.wvalid;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Trace Interface
|
||||
localparam BENCHMARK_START_COLLECTION_NOP = 32'h00C00013;
|
||||
localparam BENCHMARK_END_COLLECTION_NOP = 32'h00D00013;
|
||||
|
||||
logic start_collection;
|
||||
logic end_collection;
|
||||
|
||||
//NOP detection
|
||||
always_comb begin
|
||||
start_collection = 0;
|
||||
end_collection = 0;
|
||||
foreach(retire_ports_valid[i]) begin
|
||||
start_collection |= retire_ports_valid[i] & (retire_ports_instruction[i] == BENCHMARK_START_COLLECTION_NOP);
|
||||
end_collection |= retire_ports_valid[i] & (retire_ports_instruction[i] == BENCHMARK_END_COLLECTION_NOP);
|
||||
end
|
||||
end
|
||||
|
||||
//Hierarchy paths for major components
|
||||
`define FETCH_P cpu.fetch_block
|
||||
`define ICACHE_P cpu.fetch_block.gen_fetch_icache.i_cache
|
||||
`define BRANCH_P cpu.branch_unit_block
|
||||
`define ISSUE_P cpu.decode_and_issue_block
|
||||
`define RENAME_P cpu.renamer_block
|
||||
`define METADATA_P cpu.id_block
|
||||
`define LS_P cpu.load_store_unit_block
|
||||
`define LSQ_P cpu.load_store_unit_block.lsq_block
|
||||
`define DCACHE_P cpu.load_store_unit_block.gen_ls_dcache.data_cache
|
||||
|
||||
stats_t stats_enum;
|
||||
instruction_mix_stats_t instruction_mix_enum;
|
||||
localparam NUM_STATS = stats_enum.num();
|
||||
localparam NUM_INSTRUCTION_MIX_STATS = instruction_mix_enum.num();
|
||||
|
||||
logic stats [NUM_STATS];
|
||||
logic is_mul [RETIRE_PORTS];
|
||||
logic is_div [RETIRE_PORTS];
|
||||
logic [NUM_INSTRUCTION_MIX_STATS-1:0] instruction_mix_stats [RETIRE_PORTS];
|
||||
|
||||
logic icache_hit;
|
||||
logic icache_miss;
|
||||
logic iarb_stall;
|
||||
logic dcache_hit;
|
||||
logic dcache_miss;
|
||||
logic darb_stall;
|
||||
|
||||
//Issue stalls
|
||||
logic base_no_instruction_stall;
|
||||
logic base_no_id_sub_stall;
|
||||
logic base_flush_sub_stall;
|
||||
logic base_unit_busy_stall;
|
||||
logic base_operands_stall;
|
||||
logic base_hold_stall;
|
||||
logic single_source_issue_stall;
|
||||
|
||||
logic [3:0] stall_source_count;
|
||||
///////////////
|
||||
|
||||
//Issue phys_rd to unit mem
|
||||
//Used for determining what outputs an operand stall is waiting on
|
||||
logic [`ISSUE_P.NUM_UNITS-1:0] phys_addr_table [64];
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (cpu.instruction_issued_with_rd)
|
||||
phys_addr_table[`ISSUE_P.issue.phys_rd_addr] <= `ISSUE_P.unit_needed_issue_stage;
|
||||
end
|
||||
|
||||
generate if (NEXYS_CONFIG.INCLUDE_ICACHE) begin
|
||||
assign icache_hit = `ICACHE_P.tag_hit;
|
||||
assign icache_miss = `ICACHE_P.second_cycle & ~`ICACHE_P.tag_hit;
|
||||
assign iarb_stall = `ICACHE_P.request_r & ~cpu.l1_request[L1_ICACHE_ID].ack;
|
||||
end endgenerate
|
||||
|
||||
generate if (NEXYS_CONFIG.INCLUDE_DCACHE) begin
|
||||
assign dcache_hit = `DCACHE_P.load_hit;
|
||||
assign dcache_miss = `DCACHE_P.line_complete;
|
||||
assign darb_stall = cpu.l1_request[L1_DCACHE_ID].request & ~cpu.l1_request[L1_DCACHE_ID].ack;
|
||||
end endgenerate
|
||||
|
||||
always_comb begin
|
||||
stats = '{default: '0};
|
||||
//Fetch
|
||||
stats[FETCH_EARLY_BR_CORRECTION_STAT] = `FETCH_P.early_branch_flush;
|
||||
stats[FETCH_SUB_UNIT_STALL_STAT] = `METADATA_P.pc_id_available & ~`FETCH_P.units_ready;
|
||||
stats[FETCH_ID_STALL_STAT] = ~`METADATA_P.pc_id_available;
|
||||
stats[FETCH_IC_HIT_STAT] = icache_hit;
|
||||
stats[FETCH_IC_MISS_STAT] = icache_miss;
|
||||
stats[FETCH_IC_ARB_STALL_STAT] = iarb_stall;
|
||||
|
||||
//Branch predictor
|
||||
stats[FETCH_BP_BR_CORRECT_STAT] = `BRANCH_P.instruction_is_completing & ~`BRANCH_P.is_return & ~`BRANCH_P.branch_flush;
|
||||
stats[FETCH_BP_BR_MISPREDICT_STAT] = `BRANCH_P.instruction_is_completing & ~`BRANCH_P.is_return & `BRANCH_P.branch_flush;
|
||||
stats[FETCH_BP_RAS_CORRECT_STAT] = `BRANCH_P.instruction_is_completing & `BRANCH_P.is_return & ~`BRANCH_P.branch_flush;
|
||||
stats[FETCH_BP_RAS_MISPREDICT_STAT] = `BRANCH_P.instruction_is_completing & `BRANCH_P.is_return & `BRANCH_P.branch_flush;
|
||||
|
||||
//Issue stalls
|
||||
base_no_instruction_stall = ~`ISSUE_P.issue.stage_valid | cpu.gc.fetch_flush;
|
||||
base_no_id_sub_stall = (`METADATA_P.post_issue_count == MAX_IDS);
|
||||
base_flush_sub_stall = cpu.gc.fetch_flush;
|
||||
base_unit_busy_stall = `ISSUE_P.issue.stage_valid & ~|`ISSUE_P.issue_ready;
|
||||
base_operands_stall = `ISSUE_P.issue.stage_valid & ~`ISSUE_P.operands_ready;
|
||||
base_hold_stall = `ISSUE_P.issue.stage_valid & (cpu.gc.issue_hold | `ISSUE_P.pre_issue_exception_pending);
|
||||
|
||||
stall_source_count = 4'(base_no_instruction_stall) + 4'(base_unit_busy_stall) + 4'(base_operands_stall) + 4'(base_hold_stall);
|
||||
single_source_issue_stall = (stall_source_count == 1);
|
||||
|
||||
//Issue stall determination
|
||||
stats[ISSUE_NO_INSTRUCTION_STAT] = base_no_instruction_stall & single_source_issue_stall;
|
||||
stats[ISSUE_NO_ID_STAT] = base_no_instruction_stall & base_no_id_sub_stall & single_source_issue_stall;
|
||||
stats[ISSUE_FLUSH_STAT] = base_no_instruction_stall & base_flush_sub_stall & single_source_issue_stall;
|
||||
stats[ISSUE_UNIT_BUSY_STAT] = base_unit_busy_stall & single_source_issue_stall;
|
||||
stats[ISSUE_OPERANDS_NOT_READY_STAT] = base_operands_stall & single_source_issue_stall;
|
||||
stats[ISSUE_HOLD_STAT] = base_hold_stall & single_source_issue_stall;
|
||||
stats[ISSUE_MULTI_SOURCE_STAT] = (base_no_instruction_stall | base_unit_busy_stall | base_operands_stall | base_hold_stall) & ~single_source_issue_stall;
|
||||
|
||||
//Misc Issue stats
|
||||
stats[ISSUE_OPERAND_STALL_FOR_BRANCH_STAT] = stats[ISSUE_OPERANDS_NOT_READY_STAT] & `ISSUE_P.unit_needed_issue_stage[`ISSUE_P.UNIT_IDS.BR];
|
||||
stats[ISSUE_STORE_WITH_FORWARDED_DATA_STAT] = `ISSUE_P.issue_to[`ISSUE_P.UNIT_IDS.LS] & `ISSUE_P.is_store_r & `ISSUE_P.ls_inputs.forwarded_store;
|
||||
stats[ISSUE_DIVIDER_RESULT_REUSE_STAT] = `ISSUE_P.issue_to[`ISSUE_P.UNIT_IDS.DIV] & `ISSUE_P.gen_decode_div_inputs.div_op_reuse;
|
||||
|
||||
//Issue Stall Source
|
||||
for (int i = 0; i < REGFILE_READ_PORTS; i++) begin
|
||||
stats[ISSUE_OPERAND_STALL_ON_LOAD_STAT] |= `ISSUE_P.issue.stage_valid & phys_addr_table[`ISSUE_P.issue_phys_rs_addr[i]][`ISSUE_P.UNIT_IDS.LS] & `ISSUE_P.rs_conflict[i] ;
|
||||
stats[ISSUE_OPERAND_STALL_ON_MULTIPLY_STAT] |= EXAMPLE_CONFIG.INCLUDE_MUL & `ISSUE_P.issue.stage_valid & phys_addr_table[`ISSUE_P.issue_phys_rs_addr[i]][`ISSUE_P.UNIT_IDS.MUL] & `ISSUE_P.rs_conflict[i] ;
|
||||
stats[ISSUE_OPERAND_STALL_ON_DIVIDE_STAT] |= EXAMPLE_CONFIG.INCLUDE_DIV & `ISSUE_P.issue.stage_valid & phys_addr_table[`ISSUE_P.issue_phys_rs_addr[i]][`ISSUE_P.UNIT_IDS.DIV] & `ISSUE_P.rs_conflict[i] ;
|
||||
end
|
||||
|
||||
//LS Stats
|
||||
stats[LSU_LOAD_BLOCKED_BY_STORE_STAT] = `LSQ_P.lq.valid & `LSQ_P.store_conflict;
|
||||
stats[LSU_SUB_UNIT_STALL_STAT] = (`LS_P.lsq.load_valid | `LS_P.lsq.store_valid) & ~`LS_P.sub_unit_ready;
|
||||
stats[LSU_DC_HIT_STAT] = dcache_hit;
|
||||
stats[LSU_DC_MISS_STAT] = dcache_miss;
|
||||
stats[LSU_DC_ARB_STALL_STAT] = darb_stall;
|
||||
|
||||
//Retire Instruction Mix
|
||||
for (int i = 0; i < RETIRE_PORTS; i++) begin
|
||||
is_mul[i] = retire_ports_instruction[i][25] & ~retire_ports_instruction[i][14];
|
||||
is_div[i] = retire_ports_instruction[i][25] & retire_ports_instruction[i][14];
|
||||
instruction_mix_stats[i][ALU_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {ARITH_T, ARITH_IMM_T, AUIPC_T, LUI_T}) & ~(is_mul[i] | is_div[i]);
|
||||
instruction_mix_stats[i][BR_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {BRANCH_T, JAL_T, JALR_T});
|
||||
instruction_mix_stats[i][MUL_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {ARITH_T}) & is_mul[i];
|
||||
instruction_mix_stats[i][DIV_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {ARITH_T}) & is_div[i];
|
||||
instruction_mix_stats[i][LOAD_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {LOAD_T, AMO_T});// & retire_ports_instruction[i][14:12] inside {LS_B_fn3, L_BU_fn3};
|
||||
instruction_mix_stats[i][STORE_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {STORE_T, AMO_T});
|
||||
instruction_mix_stats[i][MISC_STAT] = cpu.retire_port_valid[i] & (retire_ports_instruction[i][6:2] inside {SYSTEM_T, FENCE_T});
|
||||
end
|
||||
end
|
||||
|
||||
sim_stats #(.NUM_OF_STATS(NUM_STATS), .NUM_INSTRUCTION_MIX_STATS(NUM_INSTRUCTION_MIX_STATS)) stats_block (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.start_collection (start_collection),
|
||||
.end_collection (end_collection),
|
||||
.stats (stats),
|
||||
.instruction_mix_stats (instruction_mix_stats),
|
||||
.retire (cpu.retire)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Performs the lookups to provide the speculative architectural register file with
|
||||
//standard register names for simulation purposes
|
||||
logic [31:0][31:0] sim_registers_unamed_groups[NEXYS_CONFIG.NUM_WB_GROUPS];
|
||||
logic [31:0][31:0] sim_registers_unamed;
|
||||
|
||||
simulation_named_regfile sim_register;
|
||||
typedef struct packed{
|
||||
phys_addr_t phys_addr;
|
||||
logic [$clog2(NEXYS_CONFIG.NUM_WB_GROUPS)-1:0] wb_group;
|
||||
} spec_table_t;
|
||||
spec_table_t translation [32];
|
||||
genvar i, j;
|
||||
generate for (i = 0; i < 32; i++) begin : gen_reg_file_sim
|
||||
for (j = 0; j < NEXYS_CONFIG.NUM_WB_GROUPS; j++) begin
|
||||
if (FPGA_VENDOR == XILINX)
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.xilinx_gen.ram[i];
|
||||
else if (FPGA_VENDOR == INTEL)
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.intel_gen.lutrams[0].write_port.ram[i];
|
||||
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].reg_group.register_file_bank[translation[i].phys_addr];
|
||||
end
|
||||
assign sim_registers_unamed[31-i] = sim_registers_unamed_groups[translation[i].wb_group][i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign NUM_RETIRE_PORTS = RETIRE_PORTS;
|
||||
generate for (genvar i = 0; i < RETIRE_PORTS; i++) begin
|
||||
assign retire_ports_pc[i] = cpu.id_block.pc_table[cpu.retire_ids[i]];
|
||||
assign retire_ports_instruction[i] = cpu.id_block.instruction_table[cpu.retire_ids[i]];
|
||||
assign retire_ports_valid[i] = cpu.retire_port_valid[i];
|
||||
end endgenerate
|
||||
|
||||
assign store_queue_empty = cpu.load_store_status.sq_empty;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertion Binding
|
||||
|
||||
endmodule
|
241
examples/nexys/nexys_wrapper.sv
Normal file
241
examples/nexys/nexys_wrapper.sv
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright © 2017 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 nexys_wrapper
|
||||
|
||||
import cva5_config::*;
|
||||
import cva5_types::*;
|
||||
import l2_config_and_types::*;
|
||||
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
||||
// AXI SIGNALS - need these to unwrap the interface for packaging //
|
||||
input logic m_axi_arready,
|
||||
output logic m_axi_arvalid,
|
||||
output logic [31: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 [31: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 [31: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 [31:0] m_axi_wdata,
|
||||
output logic [3: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 cpu_config_t NEXYS_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 : 32'h80000000,
|
||||
RESET_MTVEC : 32'h80000000,
|
||||
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'h80000000,
|
||||
H : 32'h87FFFFFF
|
||||
},
|
||||
ICACHE : '{
|
||||
LINES : 512,
|
||||
LINE_W : 4,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
NON_CACHEABLE : '{
|
||||
L : 32'h88000000,
|
||||
H : 32'h8FFFFFFF
|
||||
}
|
||||
},
|
||||
ITLB : '{
|
||||
WAYS : 2,
|
||||
DEPTH : 64
|
||||
},
|
||||
INCLUDE_DCACHE : 1,
|
||||
DCACHE_ADDR : '{
|
||||
L : 32'h80000000,
|
||||
H : 32'h8FFFFFFF
|
||||
},
|
||||
DCACHE : '{
|
||||
LINES : 1024,
|
||||
LINE_W : 4,
|
||||
WAYS : 1,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 1,
|
||||
NON_CACHEABLE : '{
|
||||
L : 32'h88000000,
|
||||
H : 32'h8FFFFFFF
|
||||
}
|
||||
},
|
||||
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 : AXI_BUS,
|
||||
//Branch Predictor Options
|
||||
INCLUDE_BRANCH_PREDICTOR : 1,
|
||||
BP : '{
|
||||
WAYS : 2,
|
||||
ENTRIES : 512,
|
||||
RAS_ENTRIES : 8
|
||||
},
|
||||
//Writeback Options
|
||||
NUM_WB_GROUPS : 2
|
||||
};
|
||||
|
||||
//Unused outputs
|
||||
local_memory_interface instruction_bram ();
|
||||
local_memory_interface data_bram ();
|
||||
avalon_interface m_avalon ();
|
||||
wishbone_interface dwishbone ();
|
||||
wishbone_interface iwishbone ();
|
||||
axi_interface m_axi ();
|
||||
interrupt_t m_interrupt;
|
||||
interrupt_t s_interrupt;
|
||||
|
||||
//L2 and AXI
|
||||
l2_requester_interface l2 ();
|
||||
axi_interface axi ();
|
||||
|
||||
logic rst_r1, rst_r2;
|
||||
|
||||
assign axi.arready = m_axi_arready;
|
||||
assign m_axi_arvalid = axi.arvalid;
|
||||
assign m_axi_araddr = axi.araddr;
|
||||
assign m_axi_arlen = axi.arlen;
|
||||
assign m_axi_arsize = axi.arsize;
|
||||
assign m_axi_arburst = axi.arburst;
|
||||
assign m_axi_arcache = axi.arcache;
|
||||
assign m_axi_arid = axi.arid;
|
||||
|
||||
assign m_axi_rready = axi.rready;
|
||||
assign axi.rvalid = m_axi_rvalid;
|
||||
assign axi.rdata = m_axi_rdata;
|
||||
assign axi.rresp = m_axi_rresp;
|
||||
assign axi.rlast = m_axi_rlast;
|
||||
assign axi.rid = m_axi_rid;
|
||||
|
||||
assign axi.awready = m_axi_awready;
|
||||
assign m_axi_awvalid = axi.awvalid;
|
||||
assign m_axi_awaddr = axi.awaddr;
|
||||
assign m_axi_awlen = axi.awlen;
|
||||
assign m_axi_awsize = axi.awsize;
|
||||
assign m_axi_awburst = axi.awburst;
|
||||
assign m_axi_awcache = axi.awcache;
|
||||
assign m_axi_awid = axi.awid;
|
||||
|
||||
//write data
|
||||
assign axi.wready = m_axi_wready;
|
||||
assign m_axi_wvalid = axi.wvalid;
|
||||
assign m_axi_wdata = axi.wdata;
|
||||
assign m_axi_wstrb = axi.wstrb;
|
||||
assign m_axi_wlast = axi.wlast;
|
||||
|
||||
//write response
|
||||
assign m_axi_bready = axi.bready;
|
||||
assign axi.bvalid = m_axi_bvalid;
|
||||
assign axi.bresp = m_axi_bresp;
|
||||
assign axi.bid = m_axi_bid;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
rst_r1 <= rst;
|
||||
rst_r2 <= rst_r1;
|
||||
end
|
||||
|
||||
l1_to_axi arb(.*, .cpu(l2), .axi(axi));
|
||||
cva5 #(.CONFIG(NEXYS_CONFIG)) cpu(.rst(rst_r2), .*);
|
||||
|
||||
endmodule
|
||||
|
87
examples/nexys/scripts/cva5-ip-core-base.tcl
Normal file
87
examples/nexys/scripts/cva5-ip-core-base.tcl
Normal file
|
@ -0,0 +1,87 @@
|
|||
|
||||
# Set the reference directory for source file relative paths (by default the value is script directory path)
|
||||
set origin_dir [file dirname [info script]]
|
||||
|
||||
# Set the project name
|
||||
set _xil_proj_name_ "cva5_nexys_wrapper"
|
||||
|
||||
set sources_dir $origin_dir/../../../
|
||||
|
||||
# Create project
|
||||
create_project ${_xil_proj_name_} $origin_dir/${_xil_proj_name_}
|
||||
|
||||
# Set the directory path for the new project
|
||||
set proj_dir [get_property directory [current_project]]
|
||||
|
||||
|
||||
# Set project properties
|
||||
set obj [current_project]
|
||||
set_property -name "simulator_language" -value "Mixed" -objects $obj
|
||||
set_property -name "target_language" -value "Verilog" -objects $obj
|
||||
|
||||
# Create 'sources_1' fileset (if not found)
|
||||
if {[string equal [get_filesets -quiet sources_1] ""]} {
|
||||
create_fileset -srcset sources_1
|
||||
}
|
||||
|
||||
#import sources needed for blackbox packaging
|
||||
import_files -norecurse $sources_dir/examples/nexys/nexys_wrapper.sv
|
||||
import_files -norecurse $sources_dir/l2_arbiter/l2_external_interfaces.sv
|
||||
import_files -norecurse $sources_dir/local_memory/local_memory_interface.sv
|
||||
import_files -norecurse $sources_dir/core/external_interfaces.sv
|
||||
import_files -norecurse $sources_dir/core/cva5_config.sv
|
||||
import_files -norecurse $sources_dir/core/riscv_types.sv
|
||||
import_files -norecurse $sources_dir/core/cva5_types.sv
|
||||
import_files -norecurse $sources_dir/core/csr_types.sv
|
||||
import_files -norecurse $sources_dir/l2_arbiter/l2_config_and_types.sv
|
||||
|
||||
# Set IP repository paths
|
||||
set obj [get_filesets sources_1]
|
||||
set_property "ip_repo_paths" "[file normalize "$origin_dir/${_xil_proj_name_}"]" $obj
|
||||
|
||||
# Rebuild user ip_repo's index before adding any source files
|
||||
update_ip_catalog -rebuild
|
||||
|
||||
# Set 'sources_1' fileset properties
|
||||
set obj [get_filesets sources_1]
|
||||
set_property -name "top" -value "nexys_wrapper" -objects $obj
|
||||
set_property -name "top_auto_set" -value "0" -objects $obj
|
||||
set_property -name "top_file" -value " ${sources_dir}/examples/nexys/nexys_wrapper.sv" -objects $obj
|
||||
|
||||
|
||||
############## Initial IP Packaging
|
||||
ipx::package_project -import_files -force -root_dir $proj_dir
|
||||
update_compile_order -fileset sources_1
|
||||
ipx::create_xgui_files [ipx::current_core]
|
||||
ipx::update_checksums [ipx::current_core]
|
||||
ipx::save_core [ipx::current_core]
|
||||
|
||||
# To set the axi interface as aximm and port map all the signals over #
|
||||
|
||||
##### Naming
|
||||
set_property name CVA5 [ipx::current_core]
|
||||
set_property display_name CVA5_NEXYS7 [ipx::current_core]
|
||||
set_property description CVA5_NEXYS7 [ipx::current_core]
|
||||
set_property vendor {} [ipx::current_core]
|
||||
set_property vendor user [ipx::current_core]
|
||||
|
||||
##### Re-Adding of project files
|
||||
set_property ip_repo_paths $sources_dir/${_xil_proj_name_} [current_project]
|
||||
current_project $_xil_proj_name_
|
||||
update_ip_catalog
|
||||
import_files -force -fileset [get_filesets sources_1] $sources_dir/core
|
||||
import_files -force -fileset [get_filesets sources_1] $sources_dir/l2_arbiter
|
||||
import_files -force -fileset [get_filesets sources_1] $sources_dir/local_memory
|
||||
import_files -fileset [get_filesets sources_1] $sources_dir/examples/nexys/l1_to_axi.sv
|
||||
|
||||
############## Re-packaging of core
|
||||
update_compile_order -fileset sources_1
|
||||
ipx::merge_project_changes files [ipx::current_core]
|
||||
set_property core_revision 1 [ipx::current_core]
|
||||
ipx::create_xgui_files [ipx::current_core]
|
||||
ipx::update_checksums [ipx::current_core]
|
||||
ipx::save_core [ipx::current_core]
|
||||
current_project ${_xil_proj_name_}
|
||||
set_property "ip_repo_paths" "[file normalize "$origin_dir/${_xil_proj_name_} "]" $obj
|
||||
update_ip_catalog -rebuild
|
||||
|
18
examples/nexys/scripts/manual_pin_assignments.xdc
Normal file
18
examples/nexys/scripts/manual_pin_assignments.xdc
Normal file
|
@ -0,0 +1,18 @@
|
|||
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {LED[0]}]
|
||||
set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS33} [get_ports {LED[1]}]
|
||||
set_property -dict {PACKAGE_PIN J13 IOSTANDARD LVCMOS33} [get_ports {LED[2]}]
|
||||
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVCMOS33} [get_ports {LED[3]}]
|
||||
set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports {LED[4]}]
|
||||
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {LED[5]}]
|
||||
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports {LED[6]}]
|
||||
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {LED[7]}]
|
||||
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {LED[8]}]
|
||||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {LED[9]}]
|
||||
set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVCMOS33} [get_ports {LED[10]}]
|
||||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {LED[11]}]
|
||||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports {LED[12]}]
|
||||
set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports {LED[13]}]
|
||||
set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports {LED[14]}]
|
||||
set_property -dict {PACKAGE_PIN V11 IOSTANDARD LVCMOS33} [get_ports {LED[15]}]
|
||||
|
||||
|
498
examples/nexys/scripts/system.tcl
Normal file
498
examples/nexys/scripts/system.tcl
Normal file
|
@ -0,0 +1,498 @@
|
|||
|
||||
################################################################
|
||||
# This is a generated script based on design: system
|
||||
#
|
||||
# Though there are limitations about the generated script,
|
||||
# the main purpose of this utility is to make learning
|
||||
# IP Integrator Tcl commands easier.
|
||||
################################################################
|
||||
|
||||
namespace eval _tcl {
|
||||
proc get_script_folder {} {
|
||||
set script_path [file normalize [info script]]
|
||||
set script_folder [file dirname $script_path]
|
||||
return $script_folder
|
||||
}
|
||||
}
|
||||
variable script_folder
|
||||
set script_folder [_tcl::get_script_folder]
|
||||
|
||||
################################################################
|
||||
# Check if script is running in correct Vivado version.
|
||||
################################################################
|
||||
set scripts_vivado_version 2022.1
|
||||
set current_vivado_version [version -short]
|
||||
|
||||
if { [string first $scripts_vivado_version $current_vivado_version] == -1 } {
|
||||
puts ""
|
||||
catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
################################################################
|
||||
# START
|
||||
################################################################
|
||||
|
||||
# To test this script, run the following commands from Vivado Tcl console:
|
||||
# source system_script.tcl
|
||||
|
||||
# If there is no project opened, this script will create a
|
||||
# project, but make sure you do not have an existing project
|
||||
# <./myproj/project_1.xpr> in the current working folder.
|
||||
|
||||
set list_projs [get_projects -quiet]
|
||||
if { $list_projs eq "" } {
|
||||
create_project project_1 myproj -part xc7a100tcsg324-1
|
||||
set_property BOARD_PART digilentinc.com:nexys-a7-100t:part0:1.2 [current_project]
|
||||
}
|
||||
|
||||
|
||||
# CHANGE DESIGN NAME HERE
|
||||
variable design_name
|
||||
set design_name system
|
||||
|
||||
# If you do not already have an existing IP Integrator design open,
|
||||
# you can create a design using the following command:
|
||||
# create_bd_design $design_name
|
||||
|
||||
# Creating design if needed
|
||||
set errMsg ""
|
||||
set nRet 0
|
||||
|
||||
set cur_design [current_bd_design -quiet]
|
||||
set list_cells [get_bd_cells -quiet]
|
||||
|
||||
if { ${design_name} eq "" } {
|
||||
# USE CASES:
|
||||
# 1) Design_name not set
|
||||
|
||||
set errMsg "Please set the variable <design_name> to a non-empty value."
|
||||
set nRet 1
|
||||
|
||||
} elseif { ${cur_design} ne "" && ${list_cells} eq "" } {
|
||||
# USE CASES:
|
||||
# 2): Current design opened AND is empty AND names same.
|
||||
# 3): Current design opened AND is empty AND names diff; design_name NOT in project.
|
||||
# 4): Current design opened AND is empty AND names diff; design_name exists in project.
|
||||
|
||||
if { $cur_design ne $design_name } {
|
||||
common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of <design_name> from <$design_name> to <$cur_design> since current design is empty."
|
||||
set design_name [get_property NAME $cur_design]
|
||||
}
|
||||
common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..."
|
||||
|
||||
} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } {
|
||||
# USE CASES:
|
||||
# 5) Current design opened AND has components AND same names.
|
||||
|
||||
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
|
||||
set nRet 1
|
||||
} elseif { [get_files -quiet ${design_name}.bd] ne "" } {
|
||||
# USE CASES:
|
||||
# 6) Current opened design, has components, but diff names, design_name exists in project.
|
||||
# 7) No opened design, design_name exists in project.
|
||||
|
||||
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
|
||||
set nRet 2
|
||||
|
||||
} else {
|
||||
# USE CASES:
|
||||
# 8) No opened design, design_name not in project.
|
||||
# 9) Current opened design, has components, but diff names, design_name not in project.
|
||||
|
||||
common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..."
|
||||
|
||||
create_bd_design $design_name
|
||||
|
||||
common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design."
|
||||
current_bd_design $design_name
|
||||
|
||||
}
|
||||
|
||||
common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable <design_name> is equal to \"$design_name\"."
|
||||
|
||||
if { $nRet != 0 } {
|
||||
catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg}
|
||||
return $nRet
|
||||
}
|
||||
|
||||
set bCheckIPsPassed 1
|
||||
##################################################################
|
||||
# CHECK IPs
|
||||
##################################################################
|
||||
set bCheckIPs 1
|
||||
if { $bCheckIPs == 1 } {
|
||||
set list_check_ips "\
|
||||
user:user:CVA5:1.0\
|
||||
xilinx.com:ip:axi_gpio:2.0\
|
||||
xilinx.com:ip:axi_uart16550:2.0\
|
||||
xilinx.com:ip:clk_wiz:6.0\
|
||||
xilinx.com:ip:mdm:3.2\
|
||||
xilinx.com:ip:mig_7series:4.2\
|
||||
xilinx.com:ip:proc_sys_reset:5.0\
|
||||
xilinx.com:ip:xlslice:1.0\
|
||||
"
|
||||
|
||||
set list_ips_missing ""
|
||||
common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ."
|
||||
|
||||
foreach ip_vlnv $list_check_ips {
|
||||
set ip_obj [get_ipdefs -all $ip_vlnv]
|
||||
if { $ip_obj eq "" } {
|
||||
lappend list_ips_missing $ip_vlnv
|
||||
}
|
||||
}
|
||||
|
||||
if { $list_ips_missing ne "" } {
|
||||
catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." }
|
||||
set bCheckIPsPassed 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if { $bCheckIPsPassed != 1 } {
|
||||
common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above."
|
||||
return 3
|
||||
}
|
||||
|
||||
|
||||
##################################################################
|
||||
# MIG PRJ FILE TCL PROCs
|
||||
##################################################################
|
||||
|
||||
proc write_mig_file_system_mig_7series_0_0 { str_mig_prj_filepath } {
|
||||
|
||||
file mkdir [ file dirname "$str_mig_prj_filepath" ]
|
||||
set mig_prj_file [open $str_mig_prj_filepath w+]
|
||||
|
||||
puts $mig_prj_file {<?xml version="1.0" encoding="UTF-8" standalone="no" ?>}
|
||||
puts $mig_prj_file {<Project NoOfControllers="1">}
|
||||
puts $mig_prj_file { }
|
||||
puts $mig_prj_file {<!-- IMPORTANT: This is an internal file that has been generated by the MIG software. Any direct editing or changes made to this file may result in unpredictable behavior or data corruption. It is strongly advised that users do not edit the contents of this file. Re-run the MIG GUI with the required settings if any of the options provided below need to be altered. -->}
|
||||
puts $mig_prj_file { <ModuleName>system_mig_7series_0_0</ModuleName>}
|
||||
puts $mig_prj_file { <dci_inouts_inputs>1</dci_inouts_inputs>}
|
||||
puts $mig_prj_file { <dci_inputs>1</dci_inputs>}
|
||||
puts $mig_prj_file { <Debug_En>OFF</Debug_En>}
|
||||
puts $mig_prj_file { <DataDepth_En>1024</DataDepth_En>}
|
||||
puts $mig_prj_file { <LowPower_En>ON</LowPower_En>}
|
||||
puts $mig_prj_file { <XADC_En>Enabled</XADC_En>}
|
||||
puts $mig_prj_file { <TargetFPGA>xc7a100t-csg324/-1</TargetFPGA>}
|
||||
puts $mig_prj_file { <Version>4.2</Version>}
|
||||
puts $mig_prj_file { <SystemClock>No Buffer</SystemClock>}
|
||||
puts $mig_prj_file { <ReferenceClock>No Buffer</ReferenceClock>}
|
||||
puts $mig_prj_file { <SysResetPolarity>ACTIVE LOW</SysResetPolarity>}
|
||||
puts $mig_prj_file { <BankSelectionFlag>FALSE</BankSelectionFlag>}
|
||||
puts $mig_prj_file { <InternalVref>1</InternalVref>}
|
||||
puts $mig_prj_file { <dci_hr_inouts_inputs>50 Ohms</dci_hr_inouts_inputs>}
|
||||
puts $mig_prj_file { <dci_cascade>0</dci_cascade>}
|
||||
puts $mig_prj_file { <Controller number="0">}
|
||||
puts $mig_prj_file { <MemoryDevice>DDR2_SDRAM/Components/MT47H64M16HR-25E</MemoryDevice>}
|
||||
puts $mig_prj_file { <TimePeriod>5000</TimePeriod>}
|
||||
puts $mig_prj_file { <VccAuxIO>1.8V</VccAuxIO>}
|
||||
puts $mig_prj_file { <PHYRatio>2:1</PHYRatio>}
|
||||
puts $mig_prj_file { <InputClkFreq>100</InputClkFreq>}
|
||||
puts $mig_prj_file { <UIExtraClocks>1</UIExtraClocks>}
|
||||
puts $mig_prj_file { <MMCM_VCO>1200</MMCM_VCO>}
|
||||
puts $mig_prj_file { <MMCMClkOut0> 6.000</MMCMClkOut0>}
|
||||
puts $mig_prj_file { <MMCMClkOut1>1</MMCMClkOut1>}
|
||||
puts $mig_prj_file { <MMCMClkOut2>1</MMCMClkOut2>}
|
||||
puts $mig_prj_file { <MMCMClkOut3>1</MMCMClkOut3>}
|
||||
puts $mig_prj_file { <MMCMClkOut4>1</MMCMClkOut4>}
|
||||
puts $mig_prj_file { <DataWidth>16</DataWidth>}
|
||||
puts $mig_prj_file { <DeepMemory>1</DeepMemory>}
|
||||
puts $mig_prj_file { <DataMask>1</DataMask>}
|
||||
puts $mig_prj_file { <ECC>Disabled</ECC>}
|
||||
puts $mig_prj_file { <Ordering>Strict</Ordering>}
|
||||
puts $mig_prj_file { <BankMachineCnt>4</BankMachineCnt>}
|
||||
puts $mig_prj_file { <CustomPart>FALSE</CustomPart>}
|
||||
puts $mig_prj_file { <NewPartName/>}
|
||||
puts $mig_prj_file { <RowAddress>13</RowAddress>}
|
||||
puts $mig_prj_file { <ColAddress>10</ColAddress>}
|
||||
puts $mig_prj_file { <BankAddress>3</BankAddress>}
|
||||
puts $mig_prj_file { <C0_MEM_SIZE>134217728</C0_MEM_SIZE>}
|
||||
puts $mig_prj_file { <UserMemoryAddressMap>BANK_ROW_COLUMN</UserMemoryAddressMap>}
|
||||
puts $mig_prj_file { <PinSelection>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="M4" SLEW="" VCCAUX_IO="" name="ddr2_addr[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R2" SLEW="" VCCAUX_IO="" name="ddr2_addr[10]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="K5" SLEW="" VCCAUX_IO="" name="ddr2_addr[11]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="N6" SLEW="" VCCAUX_IO="" name="ddr2_addr[12]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="P4" SLEW="" VCCAUX_IO="" name="ddr2_addr[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="M6" SLEW="" VCCAUX_IO="" name="ddr2_addr[2]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="T1" SLEW="" VCCAUX_IO="" name="ddr2_addr[3]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="L3" SLEW="" VCCAUX_IO="" name="ddr2_addr[4]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="P5" SLEW="" VCCAUX_IO="" name="ddr2_addr[5]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="M2" SLEW="" VCCAUX_IO="" name="ddr2_addr[6]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="N1" SLEW="" VCCAUX_IO="" name="ddr2_addr[7]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="L4" SLEW="" VCCAUX_IO="" name="ddr2_addr[8]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="N5" SLEW="" VCCAUX_IO="" name="ddr2_addr[9]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="P2" SLEW="" VCCAUX_IO="" name="ddr2_ba[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="P3" SLEW="" VCCAUX_IO="" name="ddr2_ba[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R1" SLEW="" VCCAUX_IO="" name="ddr2_ba[2]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="L1" SLEW="" VCCAUX_IO="" name="ddr2_cas_n"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="L5" SLEW="" VCCAUX_IO="" name="ddr2_ck_n[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="L6" SLEW="" VCCAUX_IO="" name="ddr2_ck_p[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="M1" SLEW="" VCCAUX_IO="" name="ddr2_cke[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="K6" SLEW="" VCCAUX_IO="" name="ddr2_cs_n[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="T6" SLEW="" VCCAUX_IO="" name="ddr2_dm[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="U1" SLEW="" VCCAUX_IO="" name="ddr2_dm[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R7" SLEW="" VCCAUX_IO="" name="ddr2_dq[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="V5" SLEW="" VCCAUX_IO="" name="ddr2_dq[10]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="U4" SLEW="" VCCAUX_IO="" name="ddr2_dq[11]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="V4" SLEW="" VCCAUX_IO="" name="ddr2_dq[12]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="T4" SLEW="" VCCAUX_IO="" name="ddr2_dq[13]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="V1" SLEW="" VCCAUX_IO="" name="ddr2_dq[14]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="T3" SLEW="" VCCAUX_IO="" name="ddr2_dq[15]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="V6" SLEW="" VCCAUX_IO="" name="ddr2_dq[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R8" SLEW="" VCCAUX_IO="" name="ddr2_dq[2]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="U7" SLEW="" VCCAUX_IO="" name="ddr2_dq[3]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="V7" SLEW="" VCCAUX_IO="" name="ddr2_dq[4]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R6" SLEW="" VCCAUX_IO="" name="ddr2_dq[5]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="U6" SLEW="" VCCAUX_IO="" name="ddr2_dq[6]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="R5" SLEW="" VCCAUX_IO="" name="ddr2_dq[7]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="T5" SLEW="" VCCAUX_IO="" name="ddr2_dq[8]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="U3" SLEW="" VCCAUX_IO="" name="ddr2_dq[9]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="V9" SLEW="" VCCAUX_IO="" name="ddr2_dqs_n[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="V2" SLEW="" VCCAUX_IO="" name="ddr2_dqs_n[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="U9" SLEW="" VCCAUX_IO="" name="ddr2_dqs_p[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="DIFF_SSTL18_II" PADName="U2" SLEW="" VCCAUX_IO="" name="ddr2_dqs_p[1]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="M3" SLEW="" VCCAUX_IO="" name="ddr2_odt[0]"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="N4" SLEW="" VCCAUX_IO="" name="ddr2_ras_n"/>}
|
||||
puts $mig_prj_file { <Pin IN_TERM="" IOSTANDARD="SSTL18_II" PADName="N2" SLEW="" VCCAUX_IO="" name="ddr2_we_n"/>}
|
||||
puts $mig_prj_file { </PinSelection>}
|
||||
puts $mig_prj_file { <System_Control>}
|
||||
puts $mig_prj_file { <Pin Bank="Select Bank" PADName="No connect" name="sys_rst"/>}
|
||||
puts $mig_prj_file { <Pin Bank="Select Bank" PADName="No connect" name="init_calib_complete"/>}
|
||||
puts $mig_prj_file { <Pin Bank="Select Bank" PADName="No connect" name="tg_compare_error"/>}
|
||||
puts $mig_prj_file { </System_Control>}
|
||||
puts $mig_prj_file { <TimingParameters>}
|
||||
puts $mig_prj_file { <Parameters tfaw="45" tras="40" trcd="15" trefi="7.8" trfc="127.5" trp="12.5" trrd="10" trtp="7.5" twtr="7.5"/>}
|
||||
puts $mig_prj_file { </TimingParameters>}
|
||||
puts $mig_prj_file { <mrBurstLength name="Burst Length">8</mrBurstLength>}
|
||||
puts $mig_prj_file { <mrBurstType name="Burst Type">Sequential</mrBurstType>}
|
||||
puts $mig_prj_file { <mrCasLatency name="CAS Latency">3</mrCasLatency>}
|
||||
puts $mig_prj_file { <mrMode name="Mode">Normal</mrMode>}
|
||||
puts $mig_prj_file { <mrDllReset name="DLL Reset">No</mrDllReset>}
|
||||
puts $mig_prj_file { <mrPdMode name="PD Mode">Fast exit</mrPdMode>}
|
||||
puts $mig_prj_file { <mrWriteRecovery name="Write Recovery">3</mrWriteRecovery>}
|
||||
puts $mig_prj_file { <emrDllEnable name="DLL Enable">Enable-Normal</emrDllEnable>}
|
||||
puts $mig_prj_file { <emrOutputDriveStrength name="Output Drive Strength">Fullstrength</emrOutputDriveStrength>}
|
||||
puts $mig_prj_file { <emrCSSelection name="Controller Chip Select Pin">Enable</emrCSSelection>}
|
||||
puts $mig_prj_file { <emrCKSelection name="Memory Clock Selection">1</emrCKSelection>}
|
||||
puts $mig_prj_file { <emrRTT name="RTT (nominal) - ODT">50ohms</emrRTT>}
|
||||
puts $mig_prj_file { <emrPosted name="Additive Latency (AL)">0</emrPosted>}
|
||||
puts $mig_prj_file { <emrOCD name="OCD Operation">OCD Exit</emrOCD>}
|
||||
puts $mig_prj_file { <emrDQS name="DQS# Enable">Enable</emrDQS>}
|
||||
puts $mig_prj_file { <emrRDQS name="RDQS Enable">Disable</emrRDQS>}
|
||||
puts $mig_prj_file { <emrOutputs name="Outputs">Enable</emrOutputs>}
|
||||
puts $mig_prj_file { <PortInterface>AXI</PortInterface>}
|
||||
puts $mig_prj_file { <AXIParameters>}
|
||||
puts $mig_prj_file { <C0_C_RD_WR_ARB_ALGORITHM>ROUND_ROBIN</C0_C_RD_WR_ARB_ALGORITHM>}
|
||||
puts $mig_prj_file { <C0_S_AXI_ADDR_WIDTH>27</C0_S_AXI_ADDR_WIDTH>}
|
||||
puts $mig_prj_file { <C0_S_AXI_DATA_WIDTH>32</C0_S_AXI_DATA_WIDTH>}
|
||||
puts $mig_prj_file { <C0_S_AXI_ID_WIDTH>7</C0_S_AXI_ID_WIDTH>}
|
||||
puts $mig_prj_file { <C0_S_AXI_SUPPORTS_NARROW_BURST>1</C0_S_AXI_SUPPORTS_NARROW_BURST>}
|
||||
puts $mig_prj_file { </AXIParameters>}
|
||||
puts $mig_prj_file { </Controller>}
|
||||
puts $mig_prj_file {</Project>}
|
||||
|
||||
close $mig_prj_file
|
||||
}
|
||||
# End of write_mig_file_system_mig_7series_0_0()
|
||||
|
||||
|
||||
|
||||
##################################################################
|
||||
# DESIGN PROCs
|
||||
##################################################################
|
||||
|
||||
|
||||
|
||||
# Procedure to create entire design; Provide argument to make
|
||||
# procedure reusable. If parentCell is "", will use root.
|
||||
proc create_root_design { parentCell } {
|
||||
|
||||
variable script_folder
|
||||
variable design_name
|
||||
|
||||
if { $parentCell eq "" } {
|
||||
set parentCell [get_bd_cells /]
|
||||
}
|
||||
|
||||
# Get object for parentCell
|
||||
set parentObj [get_bd_cells $parentCell]
|
||||
if { $parentObj == "" } {
|
||||
catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"}
|
||||
return
|
||||
}
|
||||
|
||||
# Make sure parentObj is hier blk
|
||||
set parentType [get_property TYPE $parentObj]
|
||||
if { $parentType ne "hier" } {
|
||||
catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."}
|
||||
return
|
||||
}
|
||||
|
||||
# Save current instance; Restore later
|
||||
set oldCurInst [current_bd_instance .]
|
||||
|
||||
# Set parent object as current
|
||||
current_bd_instance $parentObj
|
||||
|
||||
|
||||
# Create interface ports
|
||||
set ddr2_sdram [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 ddr2_sdram ]
|
||||
|
||||
set dip_switches_16bits [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gpio_rtl:1.0 dip_switches_16bits ]
|
||||
|
||||
set rgb_led [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gpio_rtl:1.0 rgb_led ]
|
||||
|
||||
set usb_uart [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 usb_uart ]
|
||||
|
||||
|
||||
# Create ports
|
||||
set LED [ create_bd_port -dir O -from 15 -to 0 -type data LED ]
|
||||
set reset [ create_bd_port -dir I -type rst reset ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.POLARITY {ACTIVE_LOW} \
|
||||
] $reset
|
||||
set sys_clock [ create_bd_port -dir I -type clk -freq_hz 100000000 sys_clock ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.PHASE {0.0} \
|
||||
] $sys_clock
|
||||
|
||||
# Create instance: CVA5_0, and set properties
|
||||
set CVA5_0 [ create_bd_cell -type ip -vlnv user:user:CVA5:1.0 CVA5_0 ]
|
||||
|
||||
# Create instance: axi_gpio_0, and set properties
|
||||
set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.C_ALL_OUTPUTS_2 {1} \
|
||||
CONFIG.C_DOUT_DEFAULT_2 {0x00000001} \
|
||||
CONFIG.C_GPIO2_WIDTH {16} \
|
||||
CONFIG.C_IS_DUAL {1} \
|
||||
CONFIG.GPIO2_BOARD_INTERFACE {Custom} \
|
||||
CONFIG.GPIO_BOARD_INTERFACE {dip_switches_16bits} \
|
||||
CONFIG.USE_BOARD_FLOW {true} \
|
||||
] $axi_gpio_0
|
||||
|
||||
# Create instance: axi_gpio_1, and set properties
|
||||
set axi_gpio_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_1 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.GPIO_BOARD_INTERFACE {rgb_led} \
|
||||
CONFIG.USE_BOARD_FLOW {true} \
|
||||
] $axi_gpio_1
|
||||
|
||||
# Create instance: axi_interconnect_0, and set properties
|
||||
set axi_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_0 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.NUM_MI {4} \
|
||||
CONFIG.NUM_SI {2} \
|
||||
CONFIG.S00_HAS_DATA_FIFO {2} \
|
||||
CONFIG.S01_HAS_DATA_FIFO {2} \
|
||||
CONFIG.STRATEGY {2} \
|
||||
] $axi_interconnect_0
|
||||
|
||||
# Create instance: axi_uart16550_0, and set properties
|
||||
set axi_uart16550_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart16550_0 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.UART_BOARD_INTERFACE {usb_uart} \
|
||||
CONFIG.USE_BOARD_FLOW {true} \
|
||||
] $axi_uart16550_0
|
||||
|
||||
# Create instance: clk_wiz_0, and set properties
|
||||
set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.CLK_IN1_BOARD_INTERFACE {sys_clock} \
|
||||
CONFIG.RESET_BOARD_INTERFACE {reset} \
|
||||
CONFIG.RESET_PORT {resetn} \
|
||||
CONFIG.RESET_TYPE {ACTIVE_LOW} \
|
||||
CONFIG.USE_LOCKED {false} \
|
||||
] $clk_wiz_0
|
||||
|
||||
# Create instance: mdm_1, and set properties
|
||||
set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.C_ADDR_SIZE {32} \
|
||||
CONFIG.C_DBG_MEM_ACCESS {1} \
|
||||
CONFIG.C_MB_DBG_PORTS {0} \
|
||||
CONFIG.C_M_AXI_ADDR_WIDTH {32} \
|
||||
] $mdm_1
|
||||
|
||||
# Create instance: mig_7series_0, and set properties
|
||||
set mig_7series_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mig_7series:4.2 mig_7series_0 ]
|
||||
|
||||
# Generate the PRJ File for MIG
|
||||
set str_mig_folder [get_property IP_DIR [ get_ips [ get_property CONFIG.Component_Name $mig_7series_0 ] ] ]
|
||||
set str_mig_file_name mig_b.prj
|
||||
set str_mig_file_path ${str_mig_folder}/${str_mig_file_name}
|
||||
|
||||
write_mig_file_system_mig_7series_0_0 $str_mig_file_path
|
||||
|
||||
set_property -dict [ list \
|
||||
CONFIG.BOARD_MIG_PARAM {ddr2_sdram} \
|
||||
CONFIG.RESET_BOARD_INTERFACE {reset} \
|
||||
CONFIG.XML_INPUT_FILE {mig_b.prj} \
|
||||
] $mig_7series_0
|
||||
|
||||
# Create instance: proc_sys_reset_0, and set properties
|
||||
set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ]
|
||||
|
||||
# Create instance: xlslice_0, and set properties
|
||||
set xlslice_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_0 ]
|
||||
set_property -dict [ list \
|
||||
CONFIG.DIN_WIDTH {16} \
|
||||
] $xlslice_0
|
||||
|
||||
# Create interface connections
|
||||
connect_bd_intf_net -intf_net CVA5_0_m_axi [get_bd_intf_pins CVA5_0/m_axi] [get_bd_intf_pins axi_interconnect_0/S00_AXI]
|
||||
connect_bd_intf_net -intf_net axi_gpio_0_GPIO [get_bd_intf_ports dip_switches_16bits] [get_bd_intf_pins axi_gpio_0/GPIO]
|
||||
connect_bd_intf_net -intf_net axi_gpio_1_GPIO [get_bd_intf_ports rgb_led] [get_bd_intf_pins axi_gpio_1/GPIO]
|
||||
connect_bd_intf_net -intf_net axi_interconnect_0_M00_AXI [get_bd_intf_pins axi_interconnect_0/M00_AXI] [get_bd_intf_pins mig_7series_0/S_AXI]
|
||||
connect_bd_intf_net -intf_net axi_interconnect_0_M01_AXI [get_bd_intf_pins axi_interconnect_0/M01_AXI] [get_bd_intf_pins axi_uart16550_0/S_AXI]
|
||||
connect_bd_intf_net -intf_net axi_interconnect_0_M02_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins axi_interconnect_0/M02_AXI]
|
||||
connect_bd_intf_net -intf_net axi_interconnect_0_M03_AXI [get_bd_intf_pins axi_gpio_1/S_AXI] [get_bd_intf_pins axi_interconnect_0/M03_AXI]
|
||||
connect_bd_intf_net -intf_net axi_uart16550_0_UART [get_bd_intf_ports usb_uart] [get_bd_intf_pins axi_uart16550_0/UART]
|
||||
connect_bd_intf_net -intf_net mdm_1_M_AXI [get_bd_intf_pins axi_interconnect_0/S01_AXI] [get_bd_intf_pins mdm_1/M_AXI]
|
||||
connect_bd_intf_net -intf_net mig_7series_0_DDR2 [get_bd_intf_ports ddr2_sdram] [get_bd_intf_pins mig_7series_0/DDR2]
|
||||
|
||||
# Create port connections
|
||||
connect_bd_net -net axi_gpio_0_gpio2_io_o [get_bd_ports LED] [get_bd_pins axi_gpio_0/gpio2_io_o] [get_bd_pins xlslice_0/Din]
|
||||
connect_bd_net -net clk_wiz_0_clk_out1 [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins mig_7series_0/sys_clk_i]
|
||||
connect_bd_net -net mdm_1_Debug_SYS_Rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins proc_sys_reset_0/mb_debug_sys_rst]
|
||||
connect_bd_net -net mig_7series_0_ui_addn_clk_0 [get_bd_pins mig_7series_0/clk_ref_i] [get_bd_pins mig_7series_0/ui_addn_clk_0]
|
||||
connect_bd_net -net mig_7series_0_ui_clk [get_bd_pins CVA5_0/clk] [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins axi_gpio_1/s_axi_aclk] [get_bd_pins axi_interconnect_0/ACLK] [get_bd_pins axi_interconnect_0/M00_ACLK] [get_bd_pins axi_interconnect_0/M01_ACLK] [get_bd_pins axi_interconnect_0/M02_ACLK] [get_bd_pins axi_interconnect_0/M03_ACLK] [get_bd_pins axi_interconnect_0/S00_ACLK] [get_bd_pins axi_interconnect_0/S01_ACLK] [get_bd_pins axi_uart16550_0/s_axi_aclk] [get_bd_pins mdm_1/M_AXI_ACLK] [get_bd_pins mig_7series_0/ui_clk] [get_bd_pins proc_sys_reset_0/slowest_sync_clk]
|
||||
connect_bd_net -net mig_7series_0_ui_clk_sync_rst [get_bd_pins mig_7series_0/ui_clk_sync_rst] [get_bd_pins proc_sys_reset_0/ext_reset_in]
|
||||
connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins axi_interconnect_0/ARESETN] [get_bd_pins proc_sys_reset_0/interconnect_aresetn]
|
||||
connect_bd_net -net reset_1 [get_bd_ports reset] [get_bd_pins clk_wiz_0/resetn] [get_bd_pins mig_7series_0/sys_rst]
|
||||
connect_bd_net -net rst_clk_wiz_1_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins axi_gpio_1/s_axi_aresetn] [get_bd_pins axi_interconnect_0/M00_ARESETN] [get_bd_pins axi_interconnect_0/M01_ARESETN] [get_bd_pins axi_interconnect_0/M02_ARESETN] [get_bd_pins axi_interconnect_0/M03_ARESETN] [get_bd_pins axi_interconnect_0/S00_ARESETN] [get_bd_pins axi_interconnect_0/S01_ARESETN] [get_bd_pins axi_uart16550_0/s_axi_aresetn] [get_bd_pins mdm_1/M_AXI_ARESETN] [get_bd_pins mig_7series_0/aresetn] [get_bd_pins proc_sys_reset_0/peripheral_aresetn]
|
||||
connect_bd_net -net sys_clock_1 [get_bd_ports sys_clock] [get_bd_pins clk_wiz_0/clk_in1]
|
||||
connect_bd_net -net xlslice_0_Dout [get_bd_pins CVA5_0/rst] [get_bd_pins xlslice_0/Dout]
|
||||
|
||||
# Create address segments
|
||||
assign_bd_address -offset 0x88100000 -range 0x00010000 -target_address_space [get_bd_addr_spaces CVA5_0/m_axi] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x88200000 -range 0x00010000 -target_address_space [get_bd_addr_spaces CVA5_0/m_axi] [get_bd_addr_segs axi_gpio_1/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x88000000 -range 0x00010000 -target_address_space [get_bd_addr_spaces CVA5_0/m_axi] [get_bd_addr_segs axi_uart16550_0/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x80000000 -range 0x08000000 -target_address_space [get_bd_addr_spaces CVA5_0/m_axi] [get_bd_addr_segs mig_7series_0/memmap/memaddr] -force
|
||||
assign_bd_address -offset 0x88100000 -range 0x00010000 -target_address_space [get_bd_addr_spaces mdm_1/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x88200000 -range 0x00010000 -target_address_space [get_bd_addr_spaces mdm_1/Data] [get_bd_addr_segs axi_gpio_1/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x88000000 -range 0x00010000 -target_address_space [get_bd_addr_spaces mdm_1/Data] [get_bd_addr_segs axi_uart16550_0/S_AXI/Reg] -force
|
||||
assign_bd_address -offset 0x80000000 -range 0x08000000 -target_address_space [get_bd_addr_spaces mdm_1/Data] [get_bd_addr_segs mig_7series_0/memmap/memaddr] -force
|
||||
|
||||
|
||||
# Restore current instance
|
||||
current_bd_instance $oldCurInst
|
||||
|
||||
validate_bd_design
|
||||
save_bd_design
|
||||
}
|
||||
# End of create_root_design()
|
||||
|
||||
|
||||
##################################################################
|
||||
# MAIN FLOW
|
||||
##################################################################
|
||||
|
||||
create_root_design ""
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ $(CVA5_SIM): $(CVA5_HW_SRCS) $(CVA5_SIM_SRCS)
|
|||
-o cva5-sim \
|
||||
$(VERILATOR_LINT_IGNORE) $(VERILATOR_CFLAGS) \
|
||||
$(CVA5_SIM_SRCS) \
|
||||
$(CVA5_HW_SRCS) $(CVA5_DIR)/test_benches/sim_stats.sv $(CVA5_DIR)/test_benches/verilator/cva5_sim.sv --top-module cva5_sim
|
||||
$(CVA5_HW_SRCS) $(CVA5_DIR)/test_benches/sim_stats.sv $(CVA5_DIR)/examples/nexys/l1_to_axi.sv $(CVA5_DIR)/examples/nexys/nexys_sim.sv --top-module cva5_sim
|
||||
$(MAKE) -C $(CVA5_SIM_DIR) -f Vcva5_sim.mk
|
||||
|
||||
.PHONY: clean-cva5-sim
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue