Merge branch 'DDR-Simulation' into 'master'

Ddr simulation

See merge request sfu-rcl/Taiga-dev!4
This commit is contained in:
Eric Matthews 2020-06-03 20:39:35 +00:00
commit 14b4067796
21 changed files with 11553 additions and 1448 deletions

View file

@ -41,7 +41,7 @@ module amo_alu(
/* verilator lint_off CASEINCOMPLETE */
always_comb begin
unique case (amo_alu_inputs.op)// <--unique as not all codes are in use
case (amo_alu_inputs.op)// <--unique as not all codes are in use
AMO_SWAP : result = amo_alu_inputs.rs2;
AMO_ADD : result = amo_alu_inputs.rs1_load + amo_alu_inputs.rs2;
AMO_XOR : result = amo_alu_inputs.rs1_load ^ amo_alu_inputs.rs2;
@ -55,4 +55,5 @@ module amo_alu(
end
/* verilator lint_on CASEINCOMPLETE */
endmodule
endmodule

View file

@ -65,7 +65,6 @@ module fetch(
//Subunit signals
fetch_sub_unit_interface fetch_sub[NUM_SUB_UNITS-1:0]();
logic [NUM_SUB_UNITS-1:0] sub_unit_address_match;
logic [NUM_SUB_UNITS-1:0] last_sub_unit_id;
logic [NUM_SUB_UNITS-1:0] unit_ready;
logic [NUM_SUB_UNITS-1:0] unit_data_valid;
logic [31:0] unit_data_array [NUM_SUB_UNITS-1:0];
@ -83,9 +82,7 @@ module fetch(
logic new_mem_request;
//Cache related
logic delayed_flush;
logic [31:0] stage2_phys_address;
logic stage2_valid;
genvar i;
////////////////////////////////////////////////////
@ -174,28 +171,6 @@ module fetch(
icache i_cache (.*, .fetch_sub(fetch_sub[ICACHE_ID]));
assign cache_address_match = tlb.physical_address[31:32-MEMORY_BIT_CHECK] == MEMORY_ADDR_L[31:32-MEMORY_BIT_CHECK];
assign sub_unit_address_match[ICACHE_ID] = cache_address_match;
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) stage2_valid_m (
.clk, .rst(flush_or_rst),
.set(new_mem_request),
.clr(pre_decode_push),
.result(stage2_valid)
);
always_ff @(posedge clk) begin
if (new_mem_request)
last_sub_unit_id <= sub_unit_address_match;
end
//TODO potentially move support into cache so that we're not stalled on a request we no longer need due to a flush
//If the cache is processing a miss when a flush occurs we need to discard the result once complete
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) delayed_flush_m (
.clk, .rst,
.set(gc_fetch_flush & stage2_valid & last_sub_unit_id[ICACHE_ID] & ~fetch_sub[ICACHE_ID].data_valid),
.clr(fetch_sub[ICACHE_ID].data_valid),
.result(delayed_flush)
);
end else begin
assign delayed_flush = 0;
end
endgenerate
@ -203,7 +178,7 @@ module fetch(
//Pre-Decode Output
assign pre_decode_instruction = unit_data_array[next_unit.data_out];
assign pre_decode_pc = stage2_phys_address;
assign pre_decode_push = (~delayed_flush) & units_data_valid;//FIFO is cleared on gc_fetch_flush
assign pre_decode_push = units_data_valid;//FIFO is cleared on gc_fetch_flush
always_ff @(posedge clk) begin
if (new_mem_request) begin

View file

@ -48,6 +48,7 @@ module icache(
logic [31:0] data_out [ICACHE_WAYS-1:0];
logic [31:0] miss_data;
logic miss_in_progress;
logic miss_data_ready;
logic second_cycle;
@ -67,10 +68,10 @@ module icache(
end
always_ff @ (posedge clk) begin
if (rst)
if (rst | fetch_sub.flush)
tag_update <= 0;
else if (second_cycle)
tag_update <= icache_on & ~tag_hit; //Cache enabled, read miss
tag_update <= icache_on & ~tag_hit; //Cache enabled, read miss
else
tag_update <= 0;
end
@ -94,14 +95,27 @@ module icache(
end
//request registered
logic request;
always_ff @ (posedge clk) begin
if (rst)
l1_request.request <= 0;
if (rst | fetch_sub.flush)
request <= 0;
else if (second_cycle)
l1_request.request <= ~tag_hit | ~icache_on;
request <= ~tag_hit | ~icache_on;
else if (l1_request.ack)
l1_request.request <= 0;
request <= 0;
end
assign l1_request.request = request;
always_ff @ (posedge clk) begin
if (rst | fetch_sub.flush)
miss_in_progress <= 0;
else if (l1_request.ack)
miss_in_progress <= 1;
else if (line_complete)
miss_in_progress <= 0;
end
/*************************************
@ -118,6 +132,7 @@ module icache(
//Tag banks
itag_banks icache_tag_banks (.*,
.rst(rst | fetch_sub.flush),
.stage1_addr(fetch_sub.stage1_addr),
.stage2_addr(fetch_sub.stage2_addr),
.update_way(tag_update_way),
@ -161,7 +176,7 @@ module icache(
if (rst)
miss_data_ready <= 0;
else
miss_data_ready <= l1_response.data_valid & is_target_word;
miss_data_ready <= miss_in_progress & l1_response.data_valid & is_target_word & ~fetch_sub.flush;
end
@ -193,7 +208,7 @@ module icache(
idle <= 1;
else if (fetch_sub.new_request & ~fetch_sub.flush)
idle <= 0;
else if (memory_complete | tag_hit) //read miss OR write through complete
else if (memory_complete | tag_hit | (second_cycle & fetch_sub.flush) | (request & ~l1_request.ack & fetch_sub.flush)) //read miss OR write through complete
idle <= 1;
end

View file

@ -162,6 +162,7 @@ module l2_arbiter (
assign mem.be = mem_addr_fifo_data_out.be;
assign mem.is_amo = mem_addr_fifo_data_out.is_amo;
assign mem.amo_type_or_burst_size = mem_addr_fifo_data_out.amo_type_or_burst_size;
assign mem.id = mem_addr_fifo_data_out.id;
l2_fifo #(.DATA_WIDTH($bits(l2_mem_request_t)), .FIFO_DEPTH(L2_MEM_ADDR_FIFO_DEPTH)) input_fifo (.*, .fifo(mem_addr_fifo));

View file

@ -1,456 +0,0 @@
/*
* 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>
*/
`timescale 1ns/1ns
import tb_tools::*;
import taiga_config::*;
import taiga_types::*;
import l2_config_and_types::*;
`define MEMORY_FILE "/home/ematthew/taiga/tools/cubic.sim_init" //change this to appropriate location "/home/ematthew/Downloads/dhrystone.riscv.sim_init"
`define UART_LOG "/home/ematthew/uart.log" //change this to appropriate location
module taiga_full_simulation ();
logic [3:0] WRITE_COUNTER_MAX;
logic [3:0] READ_COUNTER_MAX;
assign READ_COUNTER_MAX = 4'b0101;
assign WRITE_COUNTER_MAX = 4'b0101;
logic simulator_clk;
logic simulator_resetn;
logic peripheral_resetn;
logic interconnect_resetn;
//axi block diagram inputs
logic axi_clk;
logic resetn;
logic sin;
//AXI memory
logic [31:0]axi_araddr;
logic [1:0]axi_arburst;
logic [3:0]axi_arcache;
logic [5:0]axi_arid;
logic [7:0]axi_arlen;
logic [0:0]axi_arlock;
logic [2:0]axi_arprot;
logic [3:0]axi_arqos;
logic axi_arready;
logic [3:0]axi_arregion;
logic [2:0]axi_arsize;
logic axi_arvalid;
logic [31:0]axi_awaddr;
logic [1:0]axi_awburst;
logic [3:0]axi_awcache;
logic [5:0]axi_awid;
logic [7:0]axi_awlen;
logic [0:0]axi_awlock;
logic [2:0]axi_awprot;
logic [3:0]axi_awqos;
logic axi_awready;
logic [3:0]axi_awregion;
logic [2:0]axi_awsize;
logic axi_awvalid;
logic [5:0]axi_bid;
logic axi_bready;
logic [1:0]axi_bresp;
logic axi_bvalid;
logic [31:0]axi_rdata;
logic [5:0]axi_rid;
logic axi_rlast;
logic axi_rready;
logic [1:0]axi_rresp;
logic axi_rvalid;
logic [31:0]axi_wdata;
logic axi_wlast;
logic axi_wready;
logic [3:0]axi_wstrb;
logic axi_wvalid;
logic [5:0]axi_wid;
axi_interface ddr_axi();
//axi block diagram outputs
logic processor_reset;
logic processor_clk;
logic sout;
logic clk;
logic rst;
logic placer_rseed;
//*****************************
assign axi_clk = simulator_clk;
assign processor_clk = simulator_clk;
assign resetn = simulator_resetn;
assign clk = simulator_clk;
assign rst = processor_reset;
local_memory_interface instruction_bram();
local_memory_interface data_bram();
axi_interface m_axi();
avalon_interface m_avalon();
wishbone_interface m_wishbone();
l2_requester_interface l2[L2_NUM_PORTS-1:0]();
l2_memory_interface mem();
trace_outputs_t tr;
logic [63:0] operand_stall;
logic [63:0] unit_stall;
logic [63:0] no_id_stall;
logic [63:0] no_instruction_stall;
logic [63:0] other_stall;
logic [63:0] instruction_issued_dec;
//Register File
logic [63:0] rs1_forwarding_needed;
logic [63:0] rs2_forwarding_needed;
logic [63:0] rs1_and_rs2_forwarding_needed;
//Branch Unit
logic [63:0] branch_misspredict;
logic [63:0] return_misspredict;
//Writeback
logic [63:0] wb_mux_contention;
logic interrupt;
logic timer_interrupt;
logic[31:0] dec_pc_debug;
logic[31:0] if2_pc_debug;
logic dec_advance_debug;
logic[31:0] dec_instruction2;
logic[31:0] dec_instruction;
integer output_file;
integer output_file2;
//assign l2[1].request = 0;
assign l2[1].request_push = 0;
assign l2[1].wr_data_push = 0;
assign l2[1].inv_ack = l2[1].inv_valid;
assign l2[1].rd_data_ack = l2[1].rd_data_valid;
sim_mem simulation_mem = new();
//RAM Block
assign instruction_bram.data_in = '0;
always_ff @(posedge processor_clk) begin
if (instruction_bram.en) begin
instruction_bram.data_out <= simulation_mem.readw(instruction_bram.addr);
simulation_mem.writew(instruction_bram.addr,instruction_bram.data_in, instruction_bram.be);
end
else begin
instruction_bram.data_out <= 0;
end
end
always_ff @(posedge processor_clk) begin
if (data_bram.en) begin
data_bram.data_out <= simulation_mem.readw(data_bram.addr);
simulation_mem.writew(data_bram.addr,data_bram.data_in, data_bram.be);
end
else begin
data_bram.data_out <= 0;
end
end
taiga uut (.*, .l2(l2[0]));
//design_2 infra(.*);
l2_arbiter l2_arb (.*, .request(l2));
axi_to_arb l2_to_mem (.*, .l2(mem));
axi_mem_sim #(`MEMORY_FILE) ddr_interface (.*, .axi(ddr_axi), .if_pc(if2_pc_debug), .dec_pc(tr.instruction_pc_dec));
always
#1 simulator_clk = ~simulator_clk;
initial begin
simulator_clk = 0;
interrupt = 0;
timer_interrupt = 0;
simulator_resetn = 0;
simulation_mem.load_program(`MEMORY_FILE, RESET_VEC);
output_file = $fopen(`UART_LOG, "w");
if (output_file == 0) begin
$error ("couldn't open log file");
$finish;
end
// output_file2 = $fopen("/home/ematthew/trace", "w");
// if (output_file2 == 0) begin
// $error ("couldn't open log file");
// $finish;
// end
do_reset();
//#1200000;
//$fclose(output_file);
//$fclose(output_file2);
//$finish;
end
task do_reset;
begin
interconnect_resetn = 1'b0;
#100 interconnect_resetn = 1'b1;
peripheral_resetn = 1'b0;
#100 peripheral_resetn = 1'b1;
processor_reset = 1'b1;
#100 processor_reset = 1'b0;
end
endtask
//read channel
logic[3:0] read_counter;
logic begin_read_counter;
always_ff @(posedge simulator_clk) begin
if (!peripheral_resetn) begin
m_axi.rvalid <= 0;
m_axi.arready <= 1; //You want it to start at ready
m_axi.rresp <= 0;
read_counter <= READ_COUNTER_MAX;
end
else begin
if(m_axi.arready == 1 && m_axi.arvalid == 1) begin
m_axi.arready <= 0;
begin_read_counter <= 1;
m_axi.rdata <= 32'hFFFFFF21;
end
if(begin_read_counter) begin
if(read_counter == 0) begin
m_axi.rvalid <= 1;
m_axi.arready <= 1;
read_counter <= READ_COUNTER_MAX;
begin_read_counter <= 0;
end
else begin
read_counter <= read_counter - 1;
m_axi.rvalid <= 0;
end
end
if(m_axi.rvalid && m_axi.rready) begin
m_axi.rvalid <= 0;
end
end
end
//Write channel
//write address
logic[3:0] write_counter;
logic begin_write_counter;
always_ff @(posedge simulator_clk) begin
if (!peripheral_resetn) begin
m_axi.wready <= 0;
m_axi.awready <= 1; //You want it to start at ready
m_axi.bresp <= 0;
write_counter <= WRITE_COUNTER_MAX;
end
else begin
if(m_axi.awready == 1 && m_axi.awvalid == 1) begin
m_axi.awready <= 0;
begin_write_counter <= 1;
end
if(begin_write_counter) begin
if(write_counter == 0) begin
m_axi.awready <= 1;
m_axi.wready <= 1;
write_counter <= WRITE_COUNTER_MAX;
begin_write_counter <= 0;
end
else begin
write_counter <= write_counter - 1;
m_axi.wready <= 0;
end
end
if(m_axi.bready == 1 && m_axi.wready) begin
m_axi.bvalid <= 1;
m_axi.bresp = 0;
end
else begin
m_axi.bvalid <= 0;
m_axi.bresp = 0;
end
if(m_axi.wready & m_axi.wvalid) begin
m_axi.wready <= 0;
end
end
end
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 = {4'b0, axi_arlen[3:0]};
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;
//Capture writes to UART
always_ff @(posedge simulator_clk) begin
//if (m_axi.awready && m_axi.awaddr[13:0] == 4096) begin
if (m_axi.wvalid && m_axi.wready && m_axi.awaddr[13:0] == 4096) begin
$fwrite(output_file, "%c",m_axi.wdata[7:0]);
$fflush(output_file);
end
end
assign sin = 0;
assign dec_instruction2 = simulation_mem.readw(tr.instruction_pc_dec[31:2]);
always_ff @(posedge simulator_clk) begin
//addi r0 r0 1
if (dec_instruction2 == 32'h00a00013) begin
$fwrite(output_file, "\noperand_stall %d\n",operand_stall);
$fwrite(output_file, "unit_stall %d\n",unit_stall);
$fwrite(output_file, "no_id_stall %d\n",no_id_stall);
$fwrite(output_file, "no_instruction_stall %d\n",no_instruction_stall);
$fwrite(output_file, "other_stall %d\n",other_stall);
$fwrite(output_file, "instruction_issued_dec %d\n",instruction_issued_dec);
$fwrite(output_file, "branch_misspredict %d\n",branch_misspredict);
$fwrite(output_file, "return_misspredict %d\n",return_misspredict);
$fwrite(output_file, "rs1_forwarding_needed %d\n",rs1_forwarding_needed);
$fwrite(output_file, "rs2_forwarding_needed %d\n",rs2_forwarding_needed);
$fwrite(output_file, "rs1_OR_rs2_forwarding_needed %d\n",rs1_forwarding_needed + rs2_forwarding_needed);
$fwrite(output_file, "rs1_AND_rs2_forwarding_needed %d\n",rs1_and_rs2_forwarding_needed);
$fclose(output_file);
$fclose(output_file2);
$finish;
end
end
always_ff @(posedge simulator_clk) begin
if (rst) begin
operand_stall = 0;
unit_stall = 0;
no_id_stall = 0;
no_instruction_stall = 0;
other_stall = 0;
instruction_issued_dec = 0;
rs1_forwarding_needed = 0;
rs2_forwarding_needed = 0;
rs1_and_rs2_forwarding_needed = 0;
branch_misspredict = 0;
return_misspredict = 0;
end
if (tr.events.operand_stall)
operand_stall <= operand_stall + 1;
if (tr.events.unit_stall)
unit_stall <= unit_stall + 1;
if (tr.events.no_id_stall)
no_id_stall <= no_id_stall + 1;
if (tr.events.no_instruction_stall)
no_instruction_stall <= no_instruction_stall + 1;
if (tr.events.other_stall)
other_stall <= other_stall + 1;
if (tr.events.instruction_issued_dec)
instruction_issued_dec <= instruction_issued_dec + 1;
if (tr.events.rs1_forwarding_needed)
rs1_forwarding_needed <= rs1_forwarding_needed + 1;
if (tr.events.rs2_forwarding_needed)
rs2_forwarding_needed <= rs2_forwarding_needed + 1;
if (tr.events.rs1_and_rs2_forwarding_needed)
rs1_and_rs2_forwarding_needed <= rs1_and_rs2_forwarding_needed + 1;
if (tr.events.branch_misspredict)
branch_misspredict <= branch_misspredict + 1;
if (tr.events.return_misspredict)
return_misspredict <= return_misspredict + 1;
end
////////////////////////////////////////////////////
// always_ff @(posedge clk) begin
// if (dec_advance_debug) begin
// $fwrite(output_file2, simulation_mem.readopcode(instruction_bram.addr));
// $fwrite(output_file2, "\n");
// end
// end
endmodule

View file

@ -1,678 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="taiga_full_simulation_behav.wdb" id="1">
<top_modules>
<top_module name="csr_types" />
<top_module name="glbl" />
<top_module name="l2_config_and_types" />
<top_module name="taiga_config" />
<top_module name="taiga_full_simulation" />
<top_module name="taiga_types" />
<top_module name="tb_tools" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="0fs"></ZoomStartTime>
<ZoomEndTime time="511000001fs"></ZoomEndTime>
<Cursor1Time time="333000000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="259"></NameColumnWidth>
<ValueColumnWidth column_width="244"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="160" />
<wvobject type="logic" fp_name="/taiga_full_simulation/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/rst">
<obj_property name="ElementShortName">rst</obj_property>
<obj_property name="ObjectShortName">rst</obj_property>
</wvobject>
<wvobject fp_name="divider7358" type="divider">
<obj_property name="label">Fetch</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/fetch_block/next_pc">
<obj_property name="ElementShortName">next_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">next_pc[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/fetch_block/if_pc">
<obj_property name="ElementShortName">if_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">if_pc[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/fetch_block/stage2_phys_address">
<obj_property name="ElementShortName">stage2_phys_address[31:0]</obj_property>
<obj_property name="ObjectShortName">stage2_phys_address[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/fetch_block/inflight_count">
<obj_property name="ElementShortName">inflight_count[2:0]</obj_property>
<obj_property name="ObjectShortName">inflight_count[2:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/space_in_inst_buffer">
<obj_property name="ElementShortName">space_in_inst_buffer</obj_property>
<obj_property name="ObjectShortName">space_in_inst_buffer</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/gc_fetch_flush">
<obj_property name="ElementShortName">gc_fetch_flush</obj_property>
<obj_property name="ObjectShortName">gc_fetch_flush</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/new_issue">
<obj_property name="ElementShortName">new_issue</obj_property>
<obj_property name="ObjectShortName">new_issue</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/new_mem_request">
<obj_property name="ElementShortName">new_mem_request</obj_property>
<obj_property name="ObjectShortName">new_mem_request</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/delayed_flush">
<obj_property name="ElementShortName">delayed_flush</obj_property>
<obj_property name="ObjectShortName">delayed_flush</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/exception">
<obj_property name="ElementShortName">exception</obj_property>
<obj_property name="ObjectShortName">exception</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/mem_valid">
<obj_property name="ElementShortName">mem_valid</obj_property>
<obj_property name="ObjectShortName">mem_valid</obj_property>
</wvobject>
<wvobject fp_name="divider7368" type="divider">
<obj_property name="label">I Cache</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/new_issue">
<obj_property name="ElementShortName">new_issue</obj_property>
<obj_property name="ObjectShortName">new_issue</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/fetch_block/l1_response/data_valid">
<obj_property name="ElementShortName">data_valid</obj_property>
<obj_property name="ObjectShortName">data_valid</obj_property>
</wvobject>
<wvobject fp_name="divider254" type="divider">
<obj_property name="label">Global Control</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/gc_unit_block/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/gc_unit_block/rst">
<obj_property name="ElementShortName">rst</obj_property>
<obj_property name="ObjectShortName">rst</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/gc_unit_block/state">
<obj_property name="ElementShortName">state[31:0]</obj_property>
<obj_property name="ObjectShortName">state[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/gc_unit_block/next_state">
<obj_property name="ElementShortName">next_state[31:0]</obj_property>
<obj_property name="ObjectShortName">next_state[31:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/gc_unit_block/gc_issue_hold">
<obj_property name="ElementShortName">gc_issue_hold</obj_property>
<obj_property name="ObjectShortName">gc_issue_hold</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/gc_unit_block/gc_issue_flush">
<obj_property name="ElementShortName">gc_issue_flush</obj_property>
<obj_property name="ObjectShortName">gc_issue_flush</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/gc_unit_block/gc_fetch_flush">
<obj_property name="ElementShortName">gc_fetch_flush</obj_property>
<obj_property name="ObjectShortName">gc_fetch_flush</obj_property>
</wvobject>
<wvobject fp_name="divider7359" type="divider">
<obj_property name="label">Decode/Issue</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/pre_decode_block/fb.instruction">
<obj_property name="ElementShortName">.instruction[31:0]</obj_property>
<obj_property name="ObjectShortName">.instruction[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/pre_decode_block/fb.pc">
<obj_property name="ElementShortName">.pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.pc[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/dec_inst_text">
<obj_property name="ElementShortName">dec_inst_text[0:511]</obj_property>
<obj_property name="ObjectShortName">dec_inst_text[0:511]</obj_property>
<obj_property name="Radix">ASCIIRADIX</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/issue_valid">
<obj_property name="ElementShortName">issue_valid</obj_property>
<obj_property name="ObjectShortName">issue_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/load_store_operands_ready">
<obj_property name="ElementShortName">load_store_operands_ready</obj_property>
<obj_property name="ObjectShortName">load_store_operands_ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/operands_ready">
<obj_property name="ElementShortName">operands_ready</obj_property>
<obj_property name="ObjectShortName">operands_ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/load_store_forward_possible">
<obj_property name="ElementShortName">load_store_forward_possible</obj_property>
<obj_property name="ObjectShortName">load_store_forward_possible</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/instruction_issued">
<obj_property name="ElementShortName">instruction_issued</obj_property>
<obj_property name="ObjectShortName">instruction_issued</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/decode_block/new_request">
<obj_property name="ElementShortName">new_request[5:0]</obj_property>
<obj_property name="ObjectShortName">new_request[5:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/decode_block/issue_ready">
<obj_property name="ElementShortName">issue_ready[5:0]</obj_property>
<obj_property name="ObjectShortName">issue_ready[5:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/decode_block/issue">
<obj_property name="ElementShortName">issue[5:0]</obj_property>
<obj_property name="ObjectShortName">issue[5:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/register_file_block/rs1_feedforward">
<obj_property name="ElementShortName">rs1_feedforward</obj_property>
<obj_property name="ObjectShortName">rs1_feedforward</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/register_file_block/rs2_feedforward">
<obj_property name="ElementShortName">rs2_feedforward</obj_property>
<obj_property name="ObjectShortName">rs2_feedforward</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/uses_rs1">
<obj_property name="ElementShortName">uses_rs1</obj_property>
<obj_property name="ObjectShortName">uses_rs1</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/uses_rs2">
<obj_property name="ElementShortName">uses_rs2</obj_property>
<obj_property name="ObjectShortName">uses_rs2</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/decode_block/uses_rd">
<obj_property name="ElementShortName">uses_rd</obj_property>
<obj_property name="ObjectShortName">uses_rd</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/decode_block/future_rd_addr">
<obj_property name="ElementShortName">future_rd_addr[4:0]</obj_property>
<obj_property name="ObjectShortName">future_rd_addr[4:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="divider3002" type="divider">
<obj_property name="label">Register File</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/register_file_block/register_inuse_tracking/clr">
<obj_property name="ElementShortName">clr</obj_property>
<obj_property name="ObjectShortName">clr</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/register_file_block/sim_register">
<obj_property name="ElementShortName">sim_register</obj_property>
<obj_property name="ObjectShortName">sim_register</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/register_file_block/register_inuse_tracking/reg_inuse_A">
<obj_property name="ElementShortName">reg_inuse_A[31:0]</obj_property>
<obj_property name="ObjectShortName">reg_inuse_A[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/register_file_block/register_inuse_tracking/reg_inuse_B">
<obj_property name="ElementShortName">reg_inuse_B[31:0]</obj_property>
<obj_property name="ObjectShortName">reg_inuse_B[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/register_file_block/register_inuse_tracking/sim_inuse">
<obj_property name="ElementShortName">sim_inuse[31:0]</obj_property>
<obj_property name="ObjectShortName">sim_inuse[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/register_file_block/in_use_by">
<obj_property name="ElementShortName">in_use_by[31:0][1:0]</obj_property>
<obj_property name="ObjectShortName">in_use_by[31:0][1:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="divider3001" type="divider">
<obj_property name="label">WB &amp; Inst queue</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/dec_inst_text">
<obj_property name="ElementShortName">dec_inst_text[0:511]</obj_property>
<obj_property name="ObjectShortName">dec_inst_text[0:511]</obj_property>
<obj_property name="Radix">ASCIIRADIX</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/id_done_new">
<obj_property name="ElementShortName">id_done_new[3:0]</obj_property>
<obj_property name="ObjectShortName">id_done_new[3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/id_done">
<obj_property name="ElementShortName">id_done[3:0]</obj_property>
<obj_property name="ObjectShortName">id_done[3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/id_done_r">
<obj_property name="ElementShortName">id_done_r[3:0]</obj_property>
<obj_property name="ObjectShortName">id_done_r[3:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/write_back_mux/ti/id_available">
<obj_property name="ElementShortName">id_available</obj_property>
<obj_property name="ObjectShortName">id_available</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/issue_id">
<obj_property name="ElementShortName">issue_id[1:0]</obj_property>
<obj_property name="ObjectShortName">issue_id[1:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/write_back_mux/ti/issued">
<obj_property name="ElementShortName">issued</obj_property>
<obj_property name="ObjectShortName">issued</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/unit_instruction_id">
<obj_property name="ElementShortName">unit_instruction_id[3:0][1:0]</obj_property>
<obj_property name="ObjectShortName">unit_instruction_id[3:0][1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/unit_rd">
<obj_property name="ElementShortName">unit_rd[3:0][31:0]</obj_property>
<obj_property name="ObjectShortName">unit_rd[3:0][31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/retired_id">
<obj_property name="ElementShortName">retired_id[1:0]</obj_property>
<obj_property name="ObjectShortName">retired_id[1:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/write_back_mux/retired">
<obj_property name="ElementShortName">retired</obj_property>
<obj_property name="ObjectShortName">retired</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/write_back_mux/retired_instruction_packet">
<obj_property name="ElementShortName">retired_instruction_packet</obj_property>
<obj_property name="ObjectShortName">retired_instruction_packet</obj_property>
</wvobject>
<wvobject fp_name="divider4416" type="divider">
<obj_property name="label">Div Unit</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /computation_complete">
<obj_property name="ElementShortName">computation_complete</obj_property>
<obj_property name="ObjectShortName">computation_complete</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /div_done">
<obj_property name="ElementShortName">div_done</obj_property>
<obj_property name="ObjectShortName">div_done</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /start_algorithm">
<obj_property name="ElementShortName">start_algorithm</obj_property>
<obj_property name="ObjectShortName">start_algorithm</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /in_progress">
<obj_property name="ElementShortName">in_progress</obj_property>
<obj_property name="ObjectShortName">in_progress</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /stage1.reuse_result">
<obj_property name="ElementShortName">.reuse_result</obj_property>
<obj_property name="ObjectShortName">.reuse_result</obj_property>
</wvobject>
<wvobject fp_name="divider3000" type="divider">
<obj_property name="label">LS Unit</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/ls_input_fifo/fifo/valid">
<obj_property name="ElementShortName">valid</obj_property>
<obj_property name="ObjectShortName">valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/input_fifo/push">
<obj_property name="ElementShortName">push</obj_property>
<obj_property name="ObjectShortName">push</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/input_fifo/pop">
<obj_property name="ElementShortName">pop</obj_property>
<obj_property name="ObjectShortName">pop</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/input_fifo/full">
<obj_property name="ElementShortName">full</obj_property>
<obj_property name="ObjectShortName">full</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/last_unit">
<obj_property name="ElementShortName">last_unit[1:0]</obj_property>
<obj_property name="ObjectShortName">last_unit[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/sub_unit_address_match">
<obj_property name="ElementShortName">sub_unit_address_match[1:0]</obj_property>
<obj_property name="ObjectShortName">sub_unit_address_match[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/current_unit">
<obj_property name="ElementShortName">current_unit[1:0]</obj_property>
<obj_property name="ObjectShortName">current_unit[1:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/unit_stall">
<obj_property name="ElementShortName">unit_stall</obj_property>
<obj_property name="ObjectShortName">unit_stall</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/issue_request">
<obj_property name="ElementShortName">issue_request</obj_property>
<obj_property name="ObjectShortName">issue_request</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/ls_inputs">
<obj_property name="ElementShortName">ls_inputs</obj_property>
<obj_property name="ObjectShortName">ls_inputs</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/stage1">
<obj_property name="ElementShortName">stage1</obj_property>
<obj_property name="ObjectShortName">stage1</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/unit_ready">
<obj_property name="ElementShortName">unit_ready[1:0]</obj_property>
<obj_property name="ObjectShortName">unit_ready[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/unit_data_valid">
<obj_property name="ElementShortName">unit_data_valid[1:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_valid[1:0]</obj_property>
<obj_property name="CustomSignalColor">#00FF00</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/load_complete">
<obj_property name="ElementShortName">load_complete</obj_property>
<obj_property name="ObjectShortName">load_complete</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/unit_data_valid">
<obj_property name="ElementShortName">unit_data_valid[1:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_valid[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/unit_data_array">
<obj_property name="ElementShortName">unit_data_array[1:0][31:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_array[1:0][31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/uut/load_store_unit_block/final_load_data">
<obj_property name="ElementShortName">final_load_data[31:0]</obj_property>
<obj_property name="ObjectShortName">final_load_data[31:0]</obj_property>
</wvobject>
<wvobject fp_name="divider2999" type="divider">
<obj_property name="label">DCache</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/load_attributes/valid">
<obj_property name="ElementShortName">valid</obj_property>
<obj_property name="ObjectShortName">valid</obj_property>
</wvobject>
<wvobject fp_name="divider2998" type="divider">
<obj_property name="label">L2</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /request_push">
<obj_property name="ElementShortName">request_push</obj_property>
<obj_property name="ObjectShortName">request_push</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/arb/requests">
<obj_property name="ElementShortName">requests[1:0]</obj_property>
<obj_property name="ObjectShortName">requests[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/arb/grantee_i">
<obj_property name="ElementShortName">grantee_i[0:0]</obj_property>
<obj_property name="ObjectShortName">grantee_i[0:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/arb/grantee_v">
<obj_property name="ElementShortName">grantee_v[1:0]</obj_property>
<obj_property name="ObjectShortName">grantee_v[1:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/arb/grantee_valid">
<obj_property name="ElementShortName">grantee_valid</obj_property>
<obj_property name="ObjectShortName">grantee_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/arb/strobe">
<obj_property name="ElementShortName">strobe</obj_property>
<obj_property name="ObjectShortName">strobe</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\input_fifos[0] /pop">
<obj_property name="ElementShortName">pop</obj_property>
<obj_property name="ObjectShortName">pop</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /request_full">
<obj_property name="ElementShortName">request_full</obj_property>
<obj_property name="ObjectShortName">request_full</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/advance">
<obj_property name="ElementShortName">advance</obj_property>
<obj_property name="ObjectShortName">advance</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /inv_valid">
<obj_property name="ElementShortName">inv_valid</obj_property>
<obj_property name="ObjectShortName">inv_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /inv_ack">
<obj_property name="ElementShortName">inv_ack</obj_property>
<obj_property name="ObjectShortName">inv_ack</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /con_result">
<obj_property name="ElementShortName">con_result</obj_property>
<obj_property name="ObjectShortName">con_result</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /con_valid">
<obj_property name="ElementShortName">con_valid</obj_property>
<obj_property name="ObjectShortName">con_valid</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/\request[0] /wr_data">
<obj_property name="ElementShortName">wr_data[31:0]</obj_property>
<obj_property name="ObjectShortName">wr_data[31:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /wr_data_push">
<obj_property name="ElementShortName">wr_data_push</obj_property>
<obj_property name="ObjectShortName">wr_data_push</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /data_full">
<obj_property name="ElementShortName">data_full</obj_property>
<obj_property name="ObjectShortName">data_full</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/\request[0] /rd_data">
<obj_property name="ElementShortName">rd_data[31:0]</obj_property>
<obj_property name="ObjectShortName">rd_data[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/\request[0] /rd_sub_id">
<obj_property name="ElementShortName">rd_sub_id[1:0]</obj_property>
<obj_property name="ObjectShortName">rd_sub_id[1:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /rd_data_valid">
<obj_property name="ElementShortName">rd_data_valid</obj_property>
<obj_property name="ObjectShortName">rd_data_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/\request[0] /rd_data_ack">
<obj_property name="ElementShortName">rd_data_ack</obj_property>
<obj_property name="ObjectShortName">rd_data_ack</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/request_pop">
<obj_property name="ElementShortName">request_pop</obj_property>
<obj_property name="ObjectShortName">request_pop</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/request_valid">
<obj_property name="ElementShortName">request_valid</obj_property>
<obj_property name="ObjectShortName">request_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/abort">
<obj_property name="ElementShortName">abort</obj_property>
<obj_property name="ObjectShortName">abort</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/mem/wr_data">
<obj_property name="ElementShortName">wr_data[31:0]</obj_property>
<obj_property name="ObjectShortName">wr_data[31:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/wr_data_valid">
<obj_property name="ElementShortName">wr_data_valid</obj_property>
<obj_property name="ObjectShortName">wr_data_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/wr_data_read">
<obj_property name="ElementShortName">wr_data_read</obj_property>
<obj_property name="ObjectShortName">wr_data_read</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/mem/rd_data">
<obj_property name="ElementShortName">rd_data[31:0]</obj_property>
<obj_property name="ObjectShortName">rd_data[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/mem/rd_id">
<obj_property name="ElementShortName">rd_id[2:0]</obj_property>
<obj_property name="ObjectShortName">rd_id[2:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/mem/rd_data_valid">
<obj_property name="ElementShortName">rd_data_valid</obj_property>
<obj_property name="ObjectShortName">rd_data_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/reserv_valid">
<obj_property name="ElementShortName">reserv_valid</obj_property>
<obj_property name="ObjectShortName">reserv_valid</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/reserv_request">
<obj_property name="ElementShortName">reserv_request</obj_property>
<obj_property name="ObjectShortName">reserv_request</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/reserv_id">
<obj_property name="ElementShortName">reserv_id[0:0]</obj_property>
<obj_property name="ObjectShortName">reserv_id[0:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/reserv_id_v">
<obj_property name="ElementShortName">reserv_id_v[1:0]</obj_property>
<obj_property name="ObjectShortName">reserv_id_v[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/new_attr">
<obj_property name="ElementShortName">new_attr</obj_property>
<obj_property name="ObjectShortName">new_attr</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/data_attributes_fifo/\genblk1.genblk1.lut_ram ">
<obj_property name="ElementShortName">\genblk1.genblk1.lut_ram [15:0][6:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.lut_ram [15:0][6:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/data_attributes_fifo/\genblk1.genblk1.read_index ">
<obj_property name="ElementShortName">\genblk1.genblk1.read_index [3:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.read_index [3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/data_attributes_fifo/\genblk1.genblk1.write_index ">
<obj_property name="ElementShortName">\genblk1.genblk1.write_index [3:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.write_index [3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_arb/current_attr">
<obj_property name="ElementShortName">current_attr</obj_property>
<obj_property name="ObjectShortName">current_attr</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/data_attributes/valid">
<obj_property name="ElementShortName">valid</obj_property>
<obj_property name="ObjectShortName">valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/data_attributes/push">
<obj_property name="ElementShortName">push</obj_property>
<obj_property name="ObjectShortName">push</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_arb/data_attributes/pop">
<obj_property name="ElementShortName">pop</obj_property>
<obj_property name="ObjectShortName">pop</obj_property>
</wvobject>
<wvobject fp_name="divider2818" type="divider">
<obj_property name="label">Mem AXI</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_araddr">
<obj_property name="ElementShortName">axi_araddr[31:0]</obj_property>
<obj_property name="ObjectShortName">axi_araddr[31:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_arready">
<obj_property name="ElementShortName">axi_arready</obj_property>
<obj_property name="ObjectShortName">axi_arready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_arvalid">
<obj_property name="ElementShortName">axi_arvalid</obj_property>
<obj_property name="ObjectShortName">axi_arvalid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_rready">
<obj_property name="ElementShortName">axi_rready</obj_property>
<obj_property name="ObjectShortName">axi_rready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_rvalid">
<obj_property name="ElementShortName">axi_rvalid</obj_property>
<obj_property name="ObjectShortName">axi_rvalid</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_awburst">
<obj_property name="ElementShortName">axi_awburst[1:0]</obj_property>
<obj_property name="ObjectShortName">axi_awburst[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_rdata">
<obj_property name="ElementShortName">axi_rdata[31:0]</obj_property>
<obj_property name="ObjectShortName">axi_rdata[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_awaddr">
<obj_property name="ElementShortName">axi_awaddr[31:0]</obj_property>
<obj_property name="ObjectShortName">axi_awaddr[31:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_awready">
<obj_property name="ElementShortName">axi_awready</obj_property>
<obj_property name="ObjectShortName">axi_awready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_awvalid">
<obj_property name="ElementShortName">axi_awvalid</obj_property>
<obj_property name="ObjectShortName">axi_awvalid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_wready">
<obj_property name="ElementShortName">axi_wready</obj_property>
<obj_property name="ObjectShortName">axi_wready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_wvalid">
<obj_property name="ElementShortName">axi_wvalid</obj_property>
<obj_property name="ObjectShortName">axi_wvalid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/axi_wlast">
<obj_property name="ElementShortName">axi_wlast</obj_property>
<obj_property name="ObjectShortName">axi_wlast</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_wdata">
<obj_property name="ElementShortName">axi_wdata[31:0]</obj_property>
<obj_property name="ObjectShortName">axi_wdata[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/l2_to_mem/axi_wstrb">
<obj_property name="ElementShortName">axi_wstrb[3:0]</obj_property>
<obj_property name="ObjectShortName">axi_wstrb[3:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/write_in_progress">
<obj_property name="ElementShortName">write_in_progress</obj_property>
<obj_property name="ObjectShortName">write_in_progress</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/l2_to_mem/write_transfer_complete">
<obj_property name="ElementShortName">write_transfer_complete</obj_property>
<obj_property name="ObjectShortName">write_transfer_complete</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/write_request_count">
<obj_property name="ElementShortName">write_request_count[47:0]</obj_property>
<obj_property name="ObjectShortName">write_request_count[47:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/read_request_count">
<obj_property name="ElementShortName">read_request_count[47:0]</obj_property>
<obj_property name="ObjectShortName">read_request_count[47:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/read_burst_count">
<obj_property name="ElementShortName">read_burst_count[31:0]</obj_property>
<obj_property name="ObjectShortName">read_burst_count[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_full_simulation/ddr_interface/axi/arlen">
<obj_property name="ElementShortName">arlen[7:0]</obj_property>
<obj_property name="ObjectShortName">arlen[7:0]</obj_property>
</wvobject>
<wvobject fp_name="divider1686" type="divider">
<obj_property name="label">FIFOs</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/load_store_unit_block/ls_input_fifo/fifo/full">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">full</obj_property>
<obj_property name="ObjectShortName">full</obj_property>
<obj_property name="label">load_store_input_full</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_full_simulation/uut/\genblk5.div_unit_block /div_input_fifo/fifo/full">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">full</obj_property>
<obj_property name="ObjectShortName">full</obj_property>
<obj_property name="label">divider_input_full</obj_property>
</wvobject>
</wave_config>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,358 @@
#include "axi_ddr_sim.h"
#include "ddr_page.h"
#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <assert.h>
using namespace std;
template <class TB>
axi_ddr_sim<TB>::axi_ddr_sim(TB * tb){
this->tb = tb;
}
template <class TB>
void axi_ddr_sim<TB>::init_signals(){
tb->ddr_axi_bresp = 0;
tb->ddr_axi_bvalid = 0;
tb->ddr_axi_rvalid = 0;
tb->ddr_axi_rdata = 0;
tb->ddr_axi_rid = 0;
tb->ddr_axi_rlast = 0;
tb->ddr_axi_rresp = 0;
tb->ddr_axi_rvalid = 0;
}
template <class TB>
axi_ddr_sim<TB>::axi_ddr_sim(string filepath, uint32_t starting_memory_location, int number_of_bytes, TB * tb){
ifstream input_memory_file;
input_memory_file.open(filepath);
string line;
uint32_t max_pages = starting_memory_location/PAGE_SIZE + number_of_bytes/PAGE_SIZE;
//Parse the uniform pages
uint32_t page_index = starting_memory_location/PAGE_SIZE;
for (; page_index < max_pages; page_index++){
ddr_page page;
for(int data_index = 0; data_index < PAGE_SIZE/4; data_index++){
getline(input_memory_file, line);
//Read 32-bit number represented through hexidecimals
page.write_data(data_index, stoul(line, 0, 16));
}
ddr_pages.insert(pair<uint32_t,ddr_page>((uint32_t)(page_index*PAGE_SIZE), page));
}
generator = default_random_engine(DELAY_SEED);
read_distribution = uniform_int_distribution<int>(MIN_DELAY_RD,MAX_DELAY_RD);
write_distribution = uniform_int_distribution<int>(MIN_DELAY_WR,MAX_DELAY_WR);
this->tb = tb;
init_signals();
printf("Done AXI Initialization: %d Pages intialized\n", page_index);
fflush(stdout);
}
template <class TB>
axi_ddr_sim<TB>::axi_ddr_sim(ifstream & input_memory_file, TB * tb){
string line;
uint32_t max_pages = DDR_SIZE/PAGE_SIZE;
//Parse the uniform pages
bool not_finished = true;
uint32_t page_index = starting_location/PAGE_SIZE;
for (; page_index < max_pages; page_index++){
ddr_page page;
for(int data_index = 0; data_index < PAGE_SIZE/4; data_index++){
not_finished = (bool)getline(input_memory_file, line);
if(!not_finished)
break;
//Read 32-bit number represented through hexidecimals
page.write_data(data_index, stoul(line, 0, 16));
}
if(!not_finished)
break;
ddr_pages.insert(pair<uint32_t,ddr_page>((uint32_t)(page_index*PAGE_SIZE), page));
fflush(stdout);
}
generator = default_random_engine(DELAY_SEED);
read_distribution = uniform_int_distribution<int>(MIN_DELAY_RD,MAX_DELAY_RD);
write_distribution = uniform_int_distribution<int>(MIN_DELAY_WR,MAX_DELAY_WR);
this->tb = tb;
init_signals();
printf("Done AXI Initialization: Started from %u\n", starting_location);
fflush(stdout);
}
template <class TB>
int axi_ddr_sim<TB>::get_data(uint32_t data_address){
uint32_t starting_address = (data_address / PAGE_SIZE) * PAGE_SIZE;
if(ddr_pages.count(starting_address)){ //If page exists
return ddr_pages[starting_address].return_data(data_address%PAGE_SIZE/4);
}
else{//If it doesn't, instantiate a new page
ddr_page page;
ddr_pages.insert(pair<uint32_t,ddr_page>(starting_address, page));
assert(ddr_pages.count(starting_address)); //Check if it was intialized
return ddr_pages[starting_address].return_data(data_address%PAGE_SIZE/4);
}
}
template <class TB>
void axi_ddr_sim<TB>::set_data(uint32_t data_address, uint32_t set_data, uint32_t byte_enable){
uint32_t data = get_data(data_address);
uint32_t starting_address = (data_address / PAGE_SIZE) * PAGE_SIZE;
data = (data & ~byte_enable) | (set_data & byte_enable);
ddr_pages[starting_address].write_data(data_address%PAGE_SIZE/4, data);
};
template <class TB>
ddr_page axi_ddr_sim<TB>::get_page(uint32_t page_address){
return ddr_pages[page_address];
}
template <class TB>
void axi_ddr_sim<TB>::parse_input_signals(){
//If the master has a write requests
if(tb->ddr_axi_awvalid && wd_ad_channel_queue.size() < MAX_INFLIGHT_WD_REQ){
AXI_write_address_channel_signals elem{tb->ddr_axi_awaddr, tb->ddr_axi_awlen, tb->ddr_axi_awsize, tb->ddr_axi_awburst,tb->ddr_axi_awcache,tb->ddr_axi_awid};
wd_ad_channel_queue.push(elem);
}
//If the master has write data
if(tb->ddr_axi_wvalid){
AXI_write_data_channel_signals elem{tb->ddr_axi_wid, tb->ddr_axi_wdata, tb->ddr_axi_wstrb, tb->ddr_axi_wlast};
w_data_channel_queue.push(elem);
}
//If the master has a read request
if(tb->ddr_axi_arvalid && rd_ad_channel_queue.size() < MAX_INFLIGHT_RD_REQ){
AXI_read_address_channel_signals elem{tb->ddr_axi_araddr, tb->ddr_axi_arlen, tb->ddr_axi_arsize, tb->ddr_axi_arburst, tb->ddr_axi_arcache, tb->ddr_axi_arid};
rd_ad_channel_queue.push(elem);
}
}
template <class TB>
void axi_ddr_sim<TB>::parse_output_signals(){
if(tb->rst ==1){
tb->ddr_axi_wready = 0;
tb->ddr_axi_arready = 0;
tb->ddr_axi_bid = 0;
tb->ddr_axi_bresp = 0;
tb->ddr_axi_bvalid = 0;
tb->ddr_axi_rid = 0;
tb->ddr_axi_rdata = 0;
tb->ddr_axi_rresp = 0;
tb->ddr_axi_rlast = 0;
//tb->ddr_axi_ruser = 0;
tb->ddr_axi_rvalid = 0;
}
else {
tb->ddr_axi_wready = 1;
//Write Req
if(wd_ad_channel_queue.size() < MAX_INFLIGHT_WD_REQ)
tb->ddr_axi_awready = 1;
else
tb->ddr_axi_awready = 0;
//Read Req
if(rd_ad_channel_queue.size() < MAX_INFLIGHT_RD_REQ)
tb->ddr_axi_arready = 1;
else
tb->ddr_axi_arready = 0;
//If we the write_response
if(w_res_channel_queue.size() > 0){
AXI_write_response_channel_signals elem = w_res_channel_queue.front();
if(tb->ddr_axi_bready)
w_res_channel_queue.pop();
tb->ddr_axi_bid = elem.bid;
tb->ddr_axi_bresp = elem.bresp;
tb->ddr_axi_bvalid = 1;
}
else{
tb->ddr_axi_bid = rand();
tb->ddr_axi_bresp = rand();
//tb->ddr_axi_buser = rand();
tb->ddr_axi_bvalid = 0;
}
//If we have the read data
if(r_data_channel_queue.size() > 0){
AXI_read_data_channel_signals elem = r_data_channel_queue.front();
if(tb->ddr_axi_rready){
//cout << "Before: " << r_data_channel_queue.size() << endl;
r_data_channel_queue.pop();
//cout << "After: " << r_data_channel_queue.size() << endl;
}
tb->ddr_axi_rid = elem.rid;
tb->ddr_axi_rdata = elem.rdata;
tb->ddr_axi_rresp = elem.rresp;
tb->ddr_axi_rlast = elem.rlast;
//tb->ddr_axi_ruser = elem.ruser;
tb->ddr_axi_rvalid = 1;
}
else{
tb->ddr_axi_rid = rand();
tb->ddr_axi_rdata = rand();
tb->ddr_axi_rresp = rand();
tb->ddr_axi_rlast = 0;
//tb->ddr_axi_ruser = rand();
tb->ddr_axi_rvalid = 0;
}
}
}
template <class TB>
void axi_ddr_sim<TB>::handle_read_req(){
if(rd_ad_channel_queue.size() > 0 ){
if(current_read_parameters.delay_cycles_left == 0){
AXI_read_data_channel_signals elem;
elem.rid = rd_ad_channel_queue.front().arid;
elem.rdata = get_data(current_read_parameters.address);
current_read_parameters.number_of_bursts_left--;
if(rd_ad_channel_queue.front().arburst == 0 ){//FIXED
//do nothing
}
else if(rd_ad_channel_queue.front().arburst == 1){ //INCR
//Increment Address by number of bytes in a burst(arsize)
current_read_parameters.address += current_read_parameters.increment;
}
else if(rd_ad_channel_queue.front().arburst == 2){ //WRAP
current_read_parameters.address += current_read_parameters.increment;
if(current_read_parameters.address == current_read_parameters.wrap_boundary + current_read_parameters.number_bytes * current_read_parameters.burst_length){
current_read_parameters.address = current_read_parameters.wrap_boundary;
}
}
elem.rresp = 0; //OKAY bx00
//elem.ruser = rd_ad_channel_queue.front().aruser;
if(current_read_parameters.number_of_bursts_left == 0){
elem.rlast = 1;
rd_ad_channel_queue.pop();
}
else
elem.rlast = 0;
r_data_channel_queue.push(elem);
}
else{
current_read_parameters.delay_cycles_left--;
}
}
}
template <class TB>
void axi_ddr_sim<TB>::handle_write_req(){
//cout << "w_data_channel_queue size: " << w_data_channel_queue.size() << endl;
//cout << "current_write_parameters.number_of_bursts_left: " << current_write_parameters.number_of_bursts_left << endl;
if(w_data_channel_queue.size() > 0 && current_write_parameters.number_of_bursts_left > 0){
if(current_write_parameters.delay_cycles_left == 0){
AXI_write_data_channel_signals elem = w_data_channel_queue.front();
w_data_channel_queue.pop();
//Calculate Byte Enable
uint32_t byte_enable = 0;
if(elem.wstrb >= 8){
byte_enable = byte_enable | 0xFF000000;
elem.wstrb -= 8;
}
if(elem.wstrb >= 4){
byte_enable = byte_enable | 0x00FF0000;
elem.wstrb -= 4;
}
if(elem.wstrb >= 2){
byte_enable = byte_enable | 0x0000FF00;
elem.wstrb -= 2;
}
if(elem.wstrb == 1){
byte_enable = byte_enable | 0x000000FF;
elem.wstrb -= 1;
}
set_data(current_write_parameters.address, elem.wdata, byte_enable);
current_write_parameters.number_of_bursts_left--;
if(wd_ad_channel_queue.front().awburst == 0 ){//FIXED
//do nothing
}
else if(wd_ad_channel_queue.front().awburst == 1){ //INCR
//Increment Address by number of bytes in a burst(arsize)
current_write_parameters.address += current_write_parameters.increment;
}
else if(wd_ad_channel_queue.front().awburst == 2){ //WRAP
current_write_parameters.address += current_write_parameters.increment;
if(current_write_parameters.address == current_write_parameters.wrap_boundary + current_write_parameters.number_bytes * current_write_parameters.burst_length){
current_write_parameters.address = current_write_parameters.wrap_boundary;
}
}
//If the Write is done
if(current_write_parameters.number_of_bursts_left == 0){
AXI_write_response_channel_signals resp_elem;
resp_elem.bid = elem.wid;
resp_elem.bresp = 0;
wd_ad_channel_queue.pop();
w_res_channel_queue.push(resp_elem);
}
}
else{
current_write_parameters.delay_cycles_left--;
}
}
}
template <class TB>
void axi_ddr_sim<TB>::update_current_read_parameters(){
//If I can serve a new read request
if(rd_ad_channel_queue.size() > 0 && current_read_parameters.number_of_bursts_left == 0){
current_read_parameters.address = rd_ad_channel_queue.front().araddr;
current_read_parameters.number_of_bursts_left = rd_ad_channel_queue.front().arlen +1;
current_read_parameters.delay_cycles_left = read_distribution(generator);
if(rd_ad_channel_queue.front().arburst == 0 ){//FIXED
current_read_parameters.increment = 0;
}
else if(rd_ad_channel_queue.front().arburst == 1){ //INCR
//Increment Address by number of bytes in a burst(arsize)
current_read_parameters.increment = pow(2,rd_ad_channel_queue.front().arsize);
}
else if(rd_ad_channel_queue.front().arburst == 2){ //WRAP
current_read_parameters.increment = pow(2,rd_ad_channel_queue.front().arsize);
current_read_parameters.number_bytes = pow(2,rd_ad_channel_queue.front().arsize);
current_read_parameters.burst_length = rd_ad_channel_queue.front().arlen +1;
current_read_parameters.wrap_boundary = (int)(current_read_parameters.address/(current_read_parameters.number_bytes * current_read_parameters.burst_length)) * (current_read_parameters.number_bytes * current_read_parameters.burst_length);
}
}
}
template <class TB>
void axi_ddr_sim<TB>::update_current_write_parameters(){
//If I can serve a new read request
if(wd_ad_channel_queue.size() > 0 && current_write_parameters.number_of_bursts_left == 0){
current_write_parameters.address = wd_ad_channel_queue.front().awaddr;
current_write_parameters.number_of_bursts_left = wd_ad_channel_queue.front().awlen +1;
current_write_parameters.delay_cycles_left = write_distribution(generator);
if(wd_ad_channel_queue.front().awburst == 0 ){//FIXED
current_write_parameters.increment = 0;
}
else if(wd_ad_channel_queue.front().awburst == 1){ //INCR
//Increment Address by number of bytes in a burst(arsize)
current_write_parameters.increment = pow(2,wd_ad_channel_queue.front().awsize);
}
else if(wd_ad_channel_queue.front().awburst == 2){ //WRAP
current_write_parameters.increment = pow(2,wd_ad_channel_queue.front().awsize);
current_write_parameters.number_bytes = pow(2,wd_ad_channel_queue.front().awsize);
current_write_parameters.burst_length = wd_ad_channel_queue.front().awlen +1;
current_write_parameters.wrap_boundary = (int)(current_write_parameters.address/(current_write_parameters.number_bytes * current_write_parameters.burst_length)) * (current_write_parameters.number_bytes * current_write_parameters.burst_length);
}
}
}
template <class TB>
void axi_ddr_sim<TB>::step(){
parse_input_signals();
update_current_read_parameters();
update_current_write_parameters();
handle_read_req();
handle_write_req();
parse_output_signals();
}

View file

@ -0,0 +1,109 @@
/*
* Copyright © 2019 Eric Matthews,Zavier Aguila 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>
* Zavier Aguila <zaguila@sfu.ca>
*/
#ifndef AXIDDR_H
#define AXIDDR_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <queue>
#include <cmath>
#include <map>
#include <random>
#include "axi_interface.h"
#include "ddr_page.h"
using namespace std;
struct addr_calculation_parameters{
uint32_t address;
uint32_t increment;
uint32_t wrap_boundary;
int number_bytes;
int burst_length;
int number_of_bursts_left;
int delay_cycles_left;
};
template <class TB>
class axi_ddr_sim{
public:
//Functions--------------------------------------------------------------
//Init instructions-----------------
axi_ddr_sim();
//Initialize DDR
axi_ddr_sim(TB * tb);
//Initialize DDR from file
axi_ddr_sim(string filepath, uint32_t starting_memory_location, int number_of_bytes, TB * tb);
axi_ddr_sim(ifstream & input_memory_file, TB * tb);
void step();
int get_data(uint32_t data_address);
ddr_page get_page(uint32_t page_address);
void set_data(uint32_t data_address, uint32_t set_data, uint32_t byte_enable);
//Queue Handling Functions-------------------------------------
//AXI Functions-------------------------------------
//Latency Randomizer
//Byte Enable Handler
//Burst Handler
//Base AXI Read Reply
//BASE AXI Write Reply
private:
default_random_engine generator;
uniform_int_distribution<int> read_distribution;
uniform_int_distribution<int> write_distribution;
//Pointers to Data
map<uint32_t,ddr_page> ddr_pages;
TB *tb;
void parse_output_signals();
void parse_input_signals();
void update_current_read_parameters();
void update_current_write_parameters();
void handle_write_req();
void handle_read_req();
void init_signals();
addr_calculation_parameters current_read_parameters{0,0,0,0};
addr_calculation_parameters current_write_parameters{0,0,0,0};
//Read Request Queue
queue<AXI_read_address_channel_signals> rd_ad_channel_queue;
//Write Request Queue
queue<AXI_write_address_channel_signals> wd_ad_channel_queue;
//Read Data Queue
queue<AXI_read_data_channel_signals> r_data_channel_queue;
//Write Data Queue
queue<AXI_write_data_channel_signals> w_data_channel_queue;
//Write Response Queue
queue<AXI_write_response_channel_signals> w_res_channel_queue;
unsigned starting_location = 0x80000000;
};
#include "axi_ddr_sim.cc"
#endif

View file

@ -0,0 +1,59 @@
#ifndef AXIINTERFACE_H
#define AXIINTERFACE_H
#include <stdint.h>
using namespace std;
struct AXI_write_address_channel_signals{
uint32_t awaddr;
uint32_t awlen;
uint32_t awsize;
uint32_t awburst;
uint32_t awcache;
uint32_t awid;
//uint32_t awready;
};
struct AXI_read_address_channel_signals{
uint32_t araddr;
uint32_t arlen;
uint32_t arsize;
uint32_t arburst;
uint32_t arcache;
uint32_t arid;
};
struct AXI_write_data_channel_signals{
uint32_t wid;
uint32_t wdata;
uint32_t wstrb;
uint32_t wlast;
//uint32_t wuser;
//uint32_t wvalid;
//uint32_t wready;
};
struct AXI_write_response_channel_signals{
uint32_t bid;
uint32_t bresp;
//uint32_t buser;
uint32_t bvalid;
//uint32_t bready;
};
struct AXI_read_data_channel_signals{
uint32_t rid;
uint32_t rdata;
uint32_t rresp;
uint32_t rlast;
//uint32_t ruser;
//uint32_t rvalid;
//uint32_t rready;
};
struct AXI_channels{
AXI_read_address_channel_signals rd_ad_channel;
AXI_write_address_channel_signals wd_ad_channel;
AXI_read_data_channel_signals r_data_channel;
AXI_write_data_channel_signals w_data_channel;
AXI_write_response_channel_signals w_res_channel;
};
#endif

View file

@ -0,0 +1,212 @@
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <queue>
#include "Vaxi_l2_test.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
////////////////////////////////////////////////////
//Trace Interface Counters
int num_entries = PAGE_SIZE * 5;
uint32_t starting_location = PAGE_SIZE*0;
struct l2_arb_inputs{
uint32_t address;
uint32_t rnw;
uint32_t burst_length;
uint32_t sub_id;
uint32_t be;
};
struct l2_arb_expected_output{
uint32_t rd_data;
uint32_t rd_sub_id;
};
queue<l2_arb_inputs> test_inputs;
queue<l2_arb_expected_output> test_expected_output;
queue<uint32_t> test_data_inputs;
void assign_read_input(uint32_t address, uint32_t burst_length, uint32_t sub_id){
l2_arb_inputs in_elem{address, 1, burst_length, sub_id};
test_inputs.push(in_elem);
};
void assign_write_input(uint32_t address, uint32_t burst_length, uint32_t sub_id, uint32_t be){
l2_arb_inputs in_elem{address, 0, burst_length, sub_id, be};
test_inputs.push(in_elem);
for(int i = burst_length-1 ; i >= 0; i--){
test_data_inputs.push(i+71);
}
};
void assign_single_write_input(uint32_t address, uint32_t sub_id, uint32_t data, uint32_t be){
l2_arb_inputs in_elem{address, 0, 1, sub_id, be};
test_inputs.push(in_elem);
test_data_inputs.push(data);
};
vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match
// what SystemC does
}
using namespace std;
int main(int argc, char **argv) {
//assign_single_write_input(0,1, 1 ,0xF);
//assign_single_write_input(0,0, 21 ,0xF);
assign_single_write_input(4,0, 22 ,0xF);
//assign_single_write_input(4,0, 23 ,0xF);
//assign_single_write_input(4,0, 25 ,0xF);
//assign_write_input(0, 4, 0, 0xF);
assign_read_input(4, 4, 0);
//assign_read_input(4, 8, 0);;
ofstream logFile, sigFile;
uint64_t cycle_cout = 0;
// Initialize Verilators variables
Verilated::commandArgs(argc, argv);
#ifdef TRACE_ON
Verilated::traceEverOn(true);
#endif
if (!argv[1]) {
cout << "Missing log file name.\n";
exit(EXIT_FAILURE);
}
if (!argv[2]) {
cout << "Missing signature file name.\n";
exit(EXIT_FAILURE);
}
logFile.open (argv[1]);
sigFile.open (argv[2]);
// Create an instance of our module under test
Vaxi_l2_test *tb = new Vaxi_l2_test;
axi_ddr_sim <Vaxi_l2_test> axi_ddr("DDR_init.txt", starting_location, num_entries, tb);
#ifdef TRACE_ON
VerilatedVcdC *verilatorWaveformTracer;
verilatorWaveformTracer = new VerilatedVcdC;
tb->trace(verilatorWaveformTracer, 99);
verilatorWaveformTracer->open("/data/sim-logs/sim_results.vcd");
#endif
cout << "--------------------------------------------------------------\n";
cout << " Starting Simulation, logging to: " << argv[1] << "\n";
cout << "--------------------------------------------------------------\n";
//Reset
for(int i = 0; i < 50;i++){
tb->rst = 1;
tb->clk = 1;
tb->eval();
tb->clk = 0;
tb->eval();
}
tb->rst = 0;
tb->clk = 1;
tb->eval();
tb->clk = 0;
tb->eval();
// Tick the clock until we are done
int number_of_data_left = 0;
while(!Verilated::gotFinish()) {
tb->clk = 1;
tb->eval();
//Specify Inputs
//Note: Current doesn't give the arbiter the address and data separate
//READ Input
if(test_inputs.size() > 0 && !tb->request_full && test_inputs.front().rnw){
l2_arb_inputs elem;
elem = test_inputs.front();
test_inputs.pop();
tb->addr = elem.address;
tb->rnw = elem.rnw;
tb->is_amo = 0;
tb->amo_type_or_burst_size = elem.burst_length;
tb->sub_id = elem.sub_id;
tb->request_push = 1;
tb->wr_data_push = 0;
}
else if(test_inputs.size() > 0 && !tb->request_full && !test_inputs.front().rnw && number_of_data_left == 0){
l2_arb_inputs elem;
elem = test_inputs.front();
tb->addr = elem.address;
tb->rnw = elem.rnw;
tb->is_amo = 0;
tb->amo_type_or_burst_size = elem.burst_length - 1;
tb->sub_id = elem.sub_id;
tb->be = elem.be;
number_of_data_left = elem.burst_length;
tb->request_push = 1;
tb->wr_data_push = 0;
}
else if(number_of_data_left > 0){
tb->request_push = 0;
if(!tb->data_full){
uint32_t data = test_data_inputs.front();
test_data_inputs.pop();
tb->wr_data = data;
tb->wr_data_push = 1;
number_of_data_left--;
if(number_of_data_left == 0)
test_inputs.pop();
}
else{
tb->wr_data_push = 0;
}
}
else{
tb->addr = rand();
tb->rnw = rand() % 2;
tb->is_amo = rand() % 2;
tb->amo_type_or_burst_size = rand();
tb->sub_id = rand();
tb->wr_data = rand();
tb->request_push = 0;
tb->wr_data_push = 0;
}
if(tb->rd_data_valid){
tb->rd_data_ack = 1;
cout << "Data Recieved: " << tb->rd_data << endl;
}
else{
tb->rd_data_ack = 0;
}
//Step
axi_ddr.step();
tb->clk = 0;
tb->eval();
cycle_cout++;
#ifdef TRACE_ON
verilatorWaveformTracer->dump(vluint32_t(cycle_cout));
#endif
}
#ifdef TRACE_ON
verilatorWaveformTracer->flush();
verilatorWaveformTracer->close();
#endif
cout << "--------------------------------------------------------------\n";
cout << " Simulation Completed\n";
logFile.close();
sigFile.close();
delete tb;
exit(EXIT_SUCCESS);
}

View file

@ -0,0 +1,311 @@
/*
* 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>
*/
import taiga_config::*;
import taiga_types::*;
import l2_config_and_types::*;
module axi_l2_test # (
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,
//L2 interface
input logic [29:0] addr,
input logic [3:0] be,
input logic rnw,
input logic is_amo,
input logic [4:0] amo_type_or_burst_size,
input logic [L2_SUB_ID_W-1:0] sub_id,
input logic request_push,
output logic request_full,
output logic [31:2] inv_addr,
output logic inv_valid,
input logic inv_ack,
output logic con_result,
output logic con_valid,
input logic [31:0] wr_data,
input logic wr_data_push,
output logic data_full,
output logic [31:0] rd_data,
output logic [L2_SUB_ID_W-1:0] rd_sub_id,
output logic rd_data_valid,
input logic rd_data_ack,
//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 logic instruction_issued,
output logic taiga_events [0:$bits(taiga_trace_events_t)-1],
output logic [31:0] instruction_pc_dec,
output logic [31:0] instruction_data_dec
);
logic [3:0] WRITE_COUNTER_MAX;
logic [3:0] READ_COUNTER_MAX;
assign READ_COUNTER_MAX = 4'b0101;
assign WRITE_COUNTER_MAX = 4'b0101;
//AXI memory
logic [31:0]axi_araddr;
logic [1:0]axi_arburst;
logic [3:0]axi_arcache;
logic [5:0]axi_arid;
logic [7:0]axi_arlen;
logic [0:0]axi_arlock;
logic [2:0]axi_arprot;
logic [3:0]axi_arqos;
logic axi_arready;
logic [3:0]axi_arregion;
logic [2:0]axi_arsize;
logic axi_arvalid;
logic [31:0]axi_awaddr;
logic [1:0]axi_awburst;
logic [3:0]axi_awcache;
logic [5:0]axi_awid;
logic [7:0]axi_awlen;
logic [0:0]axi_awlock;
logic [2:0]axi_awprot;
logic [3:0]axi_awqos;
logic axi_awready;
logic [3:0]axi_awregion;
logic [2:0]axi_awsize;
logic axi_awvalid;
logic [5:0]axi_bid;
logic axi_bready;
logic [1:0]axi_bresp;
logic axi_bvalid;
logic [31:0]axi_rdata;
logic [5:0]axi_rid;
logic axi_rlast;
logic axi_rready;
logic [1:0]axi_rresp;
logic axi_rvalid;
logic [31:0]axi_wdata;
logic axi_wlast;
logic axi_wready;
logic [3:0]axi_wstrb;
logic axi_wvalid;
logic [5:0]axi_wid;
parameter SCRATCH_MEM_KB = 128;
parameter MEM_LINES = (SCRATCH_MEM_KB*1024)/4;
logic interrupt;
logic timer_interrupt;
assign interrupt = 0;
axi_interface m_axi();
//axi_interface ddr_axi();
avalon_interface m_avalon();
wishbone_interface m_wishbone();
trace_outputs_t tr;
l2_requester_interface l2[L2_NUM_PORTS-1:0]();
l2_memory_interface mem();
local_memory_interface instruction_bram();
local_memory_interface data_bram();
// assign m_axi.arready = bus_axi_arready;
// assign bus_axi_arvalid = m_axi.arvalid;
// assign bus_axi_araddr = m_axi.araddr;
//
//
// //read data
// assign bus_axi_rready = m_axi.rready;
// assign m_axi.rvalid = bus_axi_rvalid;
// assign m_axi.rdata = bus_axi_rdata;
// assign m_axi.rresp = bus_axi_rresp;
//
// //Write channel
// //write address
// assign m_axi.awready = bus_axi_awready;
// assign bus_axi_awaddr = m_axi.awaddr;
// assign bus_axi_awvalid = m_axi.awvalid;
//
//
// //write data
// assign m_axi.wready = bus_axi_wready;
// assign bus_axi_wvalid = m_axi. wvalid;
// assign bus_axi_wdata = m_axi.wdata;
// assign bus_axi_wstrb = m_axi.wstrb;
//
// //write response
// assign bus_axi_bready = m_axi.bready;
// assign m_axi.bvalid = bus_axi_bvalid;
// assign m_axi.bresp = bus_axi_bresp;
assign l2[0].addr = addr;
assign l2[0].be = be;
assign l2[0].rnw = rnw;
assign l2[0].is_amo = is_amo;
assign l2[0].amo_type_or_burst_size = amo_type_or_burst_size;
assign l2[0].sub_id = sub_id;
assign l2[0].request_push = request_push;
assign request_full = l2[0].request_full;
assign inv_addr = l2[0].inv_addr;
assign inv_valid = l2[0].inv_valid;
assign l2[0].inv_ack = inv_ack;
assign con_result = l2[0].con_result;
assign con_valid = l2[0].con_valid;
assign l2[0].wr_data = wr_data;
assign l2[0].wr_data_push = wr_data_push;
assign data_full = l2[0].data_full;
assign rd_data = l2[0].rd_data;
assign rd_sub_id = l2[0].rd_sub_id;
assign rd_data_valid = l2[0].rd_data_valid;
assign l2[0].rd_data_ack = rd_data_ack;
assign l2[1].request_push = 0;
assign l2[1].wr_data_push = 0;
assign l2[1].inv_ack = l2[1].inv_valid;
assign l2[1].rd_data_ack = l2[1].rd_data_valid;
axi_to_arb l2_to_mem (.*, .l2(mem));
l2_arbiter l2_arb (.*, .request(l2));
////////////////////////////////////////////////////
//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
assign instruction_pc_dec = tr.instruction_pc_dec;
assign instruction_data_dec = tr.instruction_data_dec;
assign instruction_issued = tr.events.instruction_issued_dec;
logic [$bits(taiga_trace_events_t)-1:0] taiga_events_packed;
assign taiga_events_packed = tr.events;
always_comb begin
foreach(taiga_events_packed[i])
taiga_events[$bits(taiga_trace_events_t)-1-i] = taiga_events_packed[i];
end
endmodule

View file

@ -0,0 +1,10 @@
#include "ddr_page.h"
ddr_page::ddr_page(){
}
uint32_t ddr_page::return_data(int data_address){
return data[data_address];
}
void ddr_page::write_data(int data_address, int data_input){
data[data_address] = data_input;
}

View file

@ -0,0 +1,13 @@
#ifndef DDR_PAGEH
#define DDR_PAGEH
#include <stdint.h>
class ddr_page{
public:
ddr_page();
uint32_t return_data(int data_address);
void write_data(int data_address, int data);
private:
uint32_t data[PAGE_SIZE/4];
};
#endif

View file

@ -0,0 +1,36 @@
#include "axi_ddr_sim.h"
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
void DDR_file_init(string filename,int num_entries){
ofstream init_file;
init_file.open(filename);
for (int i = 0; i < num_entries; i++ ){
init_file << setfill('0') << setw(8) << hex << i << endl;
}
};
int print_DDR_init(string filepath,uint32_t starting_memory_location, int number_of_bytes){
axi_ddr_sim AXI_DDR(filepath, starting_memory_location, number_of_bytes);
ifstream input_memory_file;
input_memory_file.open(filepath);
string line;
for(int data_index = starting_memory_location; data_index < int(starting_memory_location + number_of_bytes); data_index+=4){
cout << "[" << data_index << "]: " << AXI_DDR.get_data(data_index) << endl;
}
cout << "Starting Location: " << starting_memory_location << endl;
cout << "Final value should be: " << number_of_bytes/4 - 1 << endl;
return 0;
};
int main(){
int num_entries = PAGE_SIZE * 5;
uint32_t starting_location = PAGE_SIZE*0;
DDR_file_init("DDR_init.txt",num_entries);
print_DDR_init("DDR_init.txt", starting_location, num_entries*4);
return 0;
}

View file

@ -23,6 +23,8 @@
#include <iostream>
#include "TaigaTracer.h"
//#define TRACE_ON
template <class TB>
bool TaigaTracer<TB>::check_instruction_issued(uint32_t inst) {
@ -46,16 +48,17 @@ bool TaigaTracer<TB>::has_terminated() {
template <class TB>
bool TaigaTracer<TB>::has_stalled() {
if (!tb->instruction_issued) {
stall_count++;
if (stall_count > stall_limit) {
stall_count = 0;
std::cout << "\n\nError!!!!\n";
std::cout << "Stall of " << stall_limit << " cycles detected!\n\n";
return true;
} else {
stall_count = 0;
stall_count++;
}
}
else
stall_count=0;
return false;
}
@ -86,14 +89,17 @@ void TaigaTracer<TB>::print_stats() {
template <class TB>
void TaigaTracer<TB>::reset() {
tb->clk = 0;
tb->rst = 1;
tb->eval();
for (int i=0; i <reset_length; i++)
for (int i=0; i <reset_length; i++){
tick();
}
tb->rst = 0;
reset_stats();
std::cout << "DONE System reset \n" << std::flush;
}
template <class TB>
void TaigaTracer<TB>::set_log_file(std::ofstream* logFile) {
@ -123,13 +129,21 @@ void TaigaTracer<TB>::update_memory() {
template <class TB>
void TaigaTracer<TB>::tick() {
tb->eval();
cycle_count++;
tb->clk = 1;
tb->eval();
tb->clk = 0;
tb->eval();
#ifdef TRACE_ON
verilatorWaveformTracer->dump(vluint32_t(10*cycle_count-2));
#endif
cycle_count++;
tb->clk = 0;
tb->eval();
#ifdef TRACE_ON
verilatorWaveformTracer->dump(vluint32_t(10*cycle_count));
#endif
cycle_count++;
if (check_instruction_issued(BENCHMARK_START_COLLECTION_NOP)) {
collect_stats = true;
@ -138,13 +152,14 @@ void TaigaTracer<TB>::tick() {
if (check_instruction_issued(BENCHMARK_END_COLLECTION_NOP)) {
collect_stats = false;
}
update_stats();
update_UART();
update_memory();
#ifdef TRACE_ON
verilatorWaveformTracer->dump(vluint32_t(cycle_count));
#endif
tb->clk = 1;
tb->eval();
axi_ddr->step();
update_stats();
update_UART();
update_memory();
}
template <class TB>
@ -168,10 +183,19 @@ TaigaTracer<TB>::TaigaTracer(std::ifstream& programFile) {
Verilated::traceEverOn(true);
#endif
mem = new SimMem(programFile, 128);
tb = new TB;
tb->clk = 0;
#ifdef DDR_LOAD_FILE
axi_ddr = new axi_ddr_sim<Vtaiga_local_mem>(DDR_INIT_FILE,DDR_FILE_STARTING_LOCATION,DDR_FILE_NUM_BYTES);
#else
axi_ddr = new axi_ddr_sim<Vtaiga_local_mem>(programFile, tb);
#endif
programFile.clear();
programFile.seekg(0, ios::beg);
mem = new SimMem(programFile, 128);
instruction_r = mem->read(tb->instruction_bram_addr);
data_out_r = 0;
}

View file

@ -26,7 +26,7 @@
#include <iostream>
#include <iterator>
#include "SimMem.h"
#include "axi_ddr_sim.h"
//#define TRACE_ON
#define COMPLIANCE_SIG_PHASE_NOP 0x00B00013U
@ -82,11 +82,15 @@ public:
void reset_stats();
void reset();
void tick();
void set_log_file(std::ofstream* logFile);
void start_tracer(const char *trace_file);
uint64_t get_cycle_count();
private:
//DDR Simulation
TB *tb;
private:
axi_ddr_sim<TB> * axi_ddr;
SimMem *mem;
#ifdef TRACE_ON
VerilatedVcdC *verilatorWaveformTracer;
@ -105,8 +109,9 @@ private:
void update_memory();
uint32_t instruction_r;
uint32_t data_out_r;
};
};
#include "TaigaTracer.cc"
#endif

View file

@ -1,208 +0,0 @@
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "Vtaiga_full_sim.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
//#define TRACE_ON
#define COMPLIANCE_SIG_PHASE_NOP 0x00B00013U
#define ERROR_TERMINATION_NOP 0x00F00013U
#define SUCCESS_TERMINATION_NOP 0x00A00013U
////////////////////////////////////////////////////
//Trace Interface Counters
struct TaigaTrace {
static void TaigaTrace::update_stats(Vtaiga_full_sim *tb) {
operand_stall += tb->operand_stall;
unit_stall += tb->unit_stall;
no_id_stall += tb->no_id_stall;
no_instruction_stall += tb->no_instruction_stall;
other_stall += tb->other_stall;
instruction_issued_dec += tb->instruction_issued_dec;
branch_misspredict += tb->branch_misspredict;
return_misspredict += tb->return_misspredict;
wb_mux_contention += tb->wb_mux_contention;
rs1_forwarding_needed += tb->rs1_forwarding_needed;
rs2_forwarding_needed += tb->rs2_forwarding_needed;
rs1_and_rs2_forwarding_needed += tb->rs1_and_rs2_forwarding_needed;
}
static void print_stats(std::ostream& os) {
os << " Taiga trace stats:\n";
os << "--------------------------------------------------------------\n";
os << " operand_stall: " << operand_stall << "\n";
os << " unit_stall: " << unit_stall << "\n";
os << " no_id_stall: " << no_id_stall << "\n";
os << " no_instruction_stall: " << no_instruction_stall << "\n";
os << " other_stall: " << other_stall << "\n";
os << " instruction_issued_dec: " << instruction_issued_dec << "\n";
os << " branch_misspredict: " << branch_misspredict << "\n";
os << " return_misspredict: " << return_misspredict << "\n";
os << " wb_mux_contention: " << wb_mux_contention << "\n";
os << " rs1_forwarding_needed: " << rs1_forwarding_needed << "\n";
os << " rs2_forwarding_needed: " << rs2_forwarding_needed << "\n";
os << " rs1_OR_rs2_forwarding_needed: " << rs1_forwarding_needed + rs2_forwarding_needed << "\n";
os << " rs1_AND_rs2_forwarding_needed: " << rs1_and_rs2_forwarding_needed << "\n";
os << "--------------------------------------------------------------\n\n";
}
static uint64_t operand_stall;
static uint64_t unit_stall;
static uint64_t no_id_stall;
static uint64_t no_instruction_stall;
static uint64_t other_stall;
static uint64_t instruction_issued_dec;
static uint64_t branch_misspredict;
static uint64_t return_misspredict;
static uint64_t wb_mux_contention;
static uint64_t rs1_forwarding_needed;
static uint64_t rs2_forwarding_needed;
static uint64_t rs1_and_rs2_forwarding_needed;
};
Vtaiga_local_mem
#define STALL_LIMIT 2000
bool hasStalled(Vtaiga_full_sim *tb) {
if (!tb->instruction_issued_dec) {
stall_cycles++;
if (stall_cycles > STALL_LIMIT) {
stall_cycles = 0;
std::cout << "\n\nError!!!!\n";
std::cout << "PC unchanged for at least " << STALL_LIMIT << " cycles!\n\n";
return true;
} else {
stall_cycles = 0;
}
}
return false;
}
bool complianceTestsLogPhase; //Log phase vs signature phase used for compliance tests
bool checkForControlNOPs(Vtaiga_full_sim *tb) {
//Custom nop to change to signature phase for compliance tests
if (tb->instruction_data_dec == COMPLIANCE_SIG_PHASE_NOP && tb->instruction_issued_dec) {
complianceTestsLogPhase = false;
std::cout << "\n--------------------------------------------------------------\n";
std::cout << " Signature\n";
std::cout << "--------------------------------------------------------------\n";
return false;
}//Custom nop for error termination
else if (tb->instruction_data_dec == ERROR_TERMINATION_NOP && tb->instruction_issued_dec) {
std::cout << "\n\nError!!!!\n\n";
}//Custom nop for regular termination
else if (tb->instruction_data_dec == SUCCESS_TERMINATION_NOP && tb->instruction_issued_dec) {
}
return true;
}
void performReset(Vtaiga_full_sim *tb, int numCycles) {
int reset_count = 0;
tb->rst = 1;
while(!Verilated::gotFinish()) {
if (reset_count > numCycles) {
tb->rst = 0;
return;
}
else {
reset_count++;
}
tb->clk = 1;
tb->eval();
tb->clk = 0;
tb->eval();
}
}
void handleUART(Vtaiga_full_sim *tb, bool logPhase, ofstream& logFile, ofstream& sigFile) {
if (tb->write_uart) {
std::cout << tb->uart_byte;
if (logPhase) {
logFile << tb->uart_byte;
} else {
sigFile << tb->uart_byte;
}
}
}
using namespace std;
int main(int argc, char **argv) {
uint64_t cycle_cout = 0;
TaigaTrace taigaTracer = { };//Zero initialize
ofstream logFile, sigFile;
// Initialize Verilators variables
Verilated::commandArgs(argc, argv);
#ifdef TRACE_ON
Verilated::traceEverOn(true);
#endif
if (!argv[1]) {
cout << "Missing log file name.\n";
exit(EXIT_FAILURE);
}
if (!argv[2]) {
cout << "Missing signature file name.\n";
exit(EXIT_FAILURE);
}
logFile.open (argv[1]);
sigFile.open (argv[2]);
// Create an instance of our module under test
Vtaiga_full_sim *tb = new Vtaiga_full_sim;
#ifdef TRACE_ON
VerilatedVcdC *verilatorWaveformTracer;
verilatorWaveformTracer = new VerilatedVcdC;
tb->trace(verilatorWaveformTracer, 99);
verilatorWaveformTracer->open("/data/sim-logs/sim_results.vcd");
#endif
cout << "--------------------------------------------------------------\n";
cout << " Starting Simulation, logging to: " << argv[1] << "\n";
cout << "--------------------------------------------------------------\n";
complianceTestsLogPhase = true;
performReset(tb, 64);
// Tick the clock until we are done
while(!Verilated::gotFinish()) {
tb->clk = 1;
tb->eval();
tb->clk = 0;
tb->eval();
cycle_cout++;
taigaTracer.update_stats(tb);
if (hasStalled(tb, cout)) break;
if (checkForControlNOPs(tb)) break;
handleUART(tb, complianceTestsLogPhase, logFile, sigFile);
#ifdef TRACE_ON
verilatorWaveformTracer->dump(vluint32_t(cycle_cout));
#endif
}
#ifdef TRACE_ON
verilatorWaveformTracer->flush();
verilatorWaveformTracer->close();
#endif
cout << "--------------------------------------------------------------\n";
cout << " Simulation Completed: " << cycle_cout << " cycles.\n";
taigaTracer.print_stats(cout);
logFile.close();
sigFile.close();
delete tb;
exit(EXIT_SUCCESS);
}

View file

@ -1,3 +1,4 @@
#include <stdlib.h>
#include <iostream>
#include <fstream>
@ -16,7 +17,6 @@ TaigaTracer<Vtaiga_local_mem> *taigaTracer;
//#define TRACE_ON
using namespace std;
int main(int argc, char **argv) {
ofstream logFile, sigFile;
ifstream programFile;
@ -45,6 +45,7 @@ int main(int argc, char **argv) {
logFile.open (argv[1]);
sigFile.open (argv[2]);
//printf("HW INIT:%s \n", argv[3]);
programFile.open (argv[3]);
if (!logFile.is_open()) {
@ -68,13 +69,13 @@ int main(int argc, char **argv) {
#endif
taigaTracer->reset();
cout << "--------------------------------------------------------------\n";
cout << " Starting Simulation, logging to " << argv[1] << "\n";
cout << " Starting Simulation, logging to: " << argv[1] << "\n";
cout << "--------------------------------------------------------------\n";
cout << flush;
// Tick the clock until we are done
while(!(taigaTracer->has_stalled() || taigaTracer->has_terminated())) {
taigaTracer->tick();
//Compliance Tests Signature Printing Phase
if (taigaTracer->check_instruction_issued(COMPLIANCE_SIG_PHASE_NOP)) {
std::cout << "\n--------------------------------------------------------------\n";
@ -85,7 +86,7 @@ int main(int argc, char **argv) {
}
cout << "--------------------------------------------------------------\n";
cout << " Simulation Completed. " << taigaTracer->get_cycle_count() << " cycles.\n";
cout << " Simulation Completed: " << taigaTracer->get_cycle_count() << " cycles.\n";
taigaTracer->print_stats();
logFile.close();

View file

@ -41,10 +41,10 @@ module taiga_local_mem # (
output logic [0:0]ddr_axi_arlock,
output logic [2:0]ddr_axi_arprot,
output logic [3:0]ddr_axi_arqos,
output logic ddr_axi_arready,
input logic ddr_axi_arready,
output logic [3:0]ddr_axi_arregion,
output logic [2:0]ddr_axi_arsize,
input logic ddr_axi_arvalid,
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,
@ -74,6 +74,33 @@ module taiga_local_mem # (
output logic ddr_axi_wvalid,
output logic [5:0]ddr_axi_wid,
//L2 interface
input logic [29:0] addr,
input logic [3:0] be,
input logic rnw,
input logic is_amo,
input logic [4:0] amo_type_or_burst_size,
input logic [L2_SUB_ID_W-1:0] sub_id,
input logic request_push,
output logic request_full,
output logic [31:2] inv_addr,
output logic inv_valid,
input logic inv_ack,
output logic con_result,
output logic con_valid,
input logic [31:0] wr_data,
input logic wr_data_push,
output logic data_full,
output logic [31:0] rd_data,
output logic [L2_SUB_ID_W-1:0] rd_sub_id,
output logic rd_data_valid,
input logic rd_data_ack,
// //AXI bus
// output logic [31:0]bus_axi_araddr,
// output logic [1:0]bus_axi_arburst,
@ -196,7 +223,7 @@ module taiga_local_mem # (
assign interrupt = 0;
axi_interface m_axi();
axi_interface ddr_axi();
//axi_interface ddr_axi();
avalon_interface m_avalon();
wishbone_interface m_wishbone();
@ -357,40 +384,40 @@ module taiga_local_mem # (
////////////////////////////////////////////////////
//DDR AXI interface
assign ddr_axi.araddr = ddr_axi_araddr;
assign ddr_axi.arburst = ddr_axi_arburst;
assign ddr_axi.arcache = ddr_axi_arcache;
assign ddr_axi.arid = ddr_axi_arid;
assign ddr_axi.arlen = ddr_axi_arlen;
assign ddr_axi_arready = ddr_axi.arready;
assign ddr_axi.arsize = ddr_axi_arsize;
assign ddr_axi.arvalid = ddr_axi_arvalid;
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 = ddr_axi_awaddr;
assign ddr_axi.awburst = ddr_axi_awburst;
assign ddr_axi.awcache = ddr_axi_awcache;
assign ddr_axi.awid = ddr_axi_awid;
assign ddr_axi.awlen = ddr_axi_awlen;
assign ddr_axi.awready = ddr_axi_awready;
assign ddr_axi.awvalid = ddr_axi_awvalid;
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 ddr_axi.bid = ddr_axi_bid;
assign ddr_axi_bready = ddr_axi.bready;
assign ddr_axi.bresp = ddr_axi_bresp;
assign ddr_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.rdata = ddr_axi_rdata;
assign ddr_axi.rid = ddr_axi_rid;
assign ddr_axi.rlast = ddr_axi_rlast;
assign ddr_axi_rready = ddr_axi.rready;
assign ddr_axi.rresp = ddr_axi_rresp;
assign ddr_axi.rvalid = ddr_axi_rvalid;
assign ddr_axi_wdata = ddr_axi.wdata;
assign ddr_axi_wlast = ddr_axi.wlast;
assign ddr_axi.wready = ddr_axi_wready;
assign ddr_axi_wstrb = ddr_axi.wstrb;
assign ddr_axi_wvalid = ddr_axi.wvalid;
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
@ -404,4 +431,4 @@ module taiga_local_mem # (
taiga_events[$bits(taiga_trace_events_t)-1-i] = taiga_events_packed[i];
end
endmodule
endmodule

View file

@ -3,7 +3,7 @@
#MAKEFLAGS += --silent
-include internal.mak
MAKEFILE_DIR=$(pwd)
TAIGA_DIR=/home/ematthew/taiga
TAIGA_DIR=/home/zaguila/Documents/Research/AXI_DDR_simulation/Taiga-dev
RISCV_PREFIX ?= riscv32-unknown-elf-
@ -14,29 +14,73 @@ VERILATOR_DIR=$(TAIGA_DIR)/test_benches/verilator
TAIGA_SRCS = $(shell cat taiga_compile_order)
#Set to True or False
TRACE_ENABLE=False
VERILATOR_TRACE_FILE="/data/sim-logs/sim_results.vcd"
#Tracing: Set to True or False
TRACE_ENABLE=False
VERILATOR_TRACE_FILE="/home/zaguila/Tools/RISCV/sim-logs/sim_results.vcd"
#DDR Pre-Initialization
LOAD_DDR_FROM_FILE = False
DDR_FILE = "\"path_to_DDR_init_file\""
DDR_FILE_STARTING_LOCATION = 0
DDR_FILE_NUM_BYTES = 0
#AXI DDR Parameters
DDR_SIZE_GB = 4
PAGE_SIZE_KB = 2
MAX_READ_REQ = 8
MAX_WRITE_REQ = $(MAX_READ_REQ)
MIN_RD_DELAY = 1
MAX_RD_DELAY = 1
MIN_WR_DELAY = 1
MAX_WR_DELAY = 1
DELAY_SEED = 867583
######################################################################
ddr_size_def = DDR_SIZE=\(long\)$(DDR_SIZE_GB)*\(long\)1073741824
page_size_def = PAGE_SIZE=\($(PAGE_SIZE_KB)*1024\)
max_inflight_read_requests = MAX_INFLIGHT_RD_REQ=$(MAX_READ_REQ)
max_inflight_write_requests = MAX_INFLIGHT_WD_REQ=$(MAX_WRITE_REQ)
mix_delay_read = MIN_DELAY_RD=$(MIN_RD_DELAY)
max_delay_read = MAX_DELAY_RD=$(MAX_RD_DELAY)
min_delay_write = MIN_DELAY_WR=$(MIN_WR_DELAY)
max_delay_write = MAX_DELAY_WR=$(MAX_WR_DELAY)
delay_seed = DELAY_SEED=$(DELAY_SEED)
ddr_init_file = DDR_INIT_FILE=$(DDR_FILE)
ddr_start_loc = DDR_FILE_STARTING_LOCATION=$(DDR_FILE_STARTING_LOCATION)
ddr_num_bytes = DDR_FILE_NUM_BYTES=$(DDR_FILE_NUM_BYTES)
CFLAGS = -g0 -O3 -march=native -D$(ddr_size_def) -D$(page_size_def) -D$(max_inflight_read_requests) -D$(max_inflight_write_requests)\
-D$(mix_delay_read) -D$(max_delay_read) -D$(min_delay_write) -D$(max_delay_write) -D$(delay_seed)\
-D$(ddr_init_file) -D$(ddr_start_loc) -D$(ddr_num_bytes)
#Verilator
################################################################################
VERILATOR_LINT_IGNORE= -Wno-LITENDIAN -Wno-SYMRSVDWORD
ifeq ($(TRACE_ENABLE), True)
VERILATOR_CFLAGS = --trace -CFLAGS "-g0 -O3 -march=native -D TRACE_ON"
VERILATOR_CFLAGS = --trace --CFLAGS "$(CFLAGS) -D TRACE_ON"
else
VERILATOR_CFLAGS = -CFLAGS "-g0 -O3 -march=native"
VERILATOR_CFLAGS = --CFLAGS "$(CFLAGS)"
endif
###############################################################
VERILATOR_LINT_IGNORE= -Wno-LITENDIAN -Wno-SYMRSVDWORD
ifeq ($(LOAD_DDR_FROM_FILE), True)
VERILATOR_CFLAGS := $(VERILATOR_CFLAGS) -D LOAD_DDR_FROM_FILE"
endif
##################################################################################
#Compiance parameters
###############################################################
COMPLIANCE_DIR=/home/ematthew/Research/RISCV/sfu-rcl/taiga-riscv-compliance/
COMPLIANCE_DIR=/home/zaguila/Tools/RISCV/taiga-riscv-compliance/
COMPLIANCE_TARGET=rv32im
###############################################################
#Benchmark parameters
#Assumes binaries are in the BENCHMARK_DIR
###############################################################
EMBENCH_DIR=/home/ematthew/Research/RISCV/sfu-rcl/taiga-embench
EMBENCH_BENCHMARKS = \
EMBENCH_DIR=/home/zaguila/Tools/RISCV/taiga-embench
EMBENCH_BENCHMARKS = \
aha-mont64 \
crc32 \
cubic \
@ -56,6 +100,7 @@ st \
statemate \
ud \
wikisort \
embench_logs = $(addsuffix _full.log, $(EMBENCH_BENCHMARKS))
embench_hw = $(addsuffix .hw_init, $(EMBENCH_BENCHMARKS))
@ -118,8 +163,13 @@ build_taiga_sim: $(TAIGA_SRCS)
cp $(VERILATOR_DIR)/SimMem.h $@/
cp $(VERILATOR_DIR)/SimMem.cc $@/
cp $(VERILATOR_DIR)/taiga_local_mem.cc $@/
cp $(VERILATOR_DIR)/AXI_DDR_simulation/axi_ddr_sim.cc $@/
cp $(VERILATOR_DIR)/AXI_DDR_simulation/axi_ddr_sim.h $@/
cp $(VERILATOR_DIR)/AXI_DDR_simulation/ddr_page.cc $@/
cp $(VERILATOR_DIR)/AXI_DDR_simulation/ddr_page.h $@/
cp $(VERILATOR_DIR)/AXI_DDR_simulation/axi_interface.h $@/
verilator --cc --exe --Mdir $@ --assert $(VERILATOR_LINT_IGNORE) $(VERILATOR_CFLAGS) $(TAIGA_SRCS) \
../test_benches/verilator/taiga_local_mem.sv --top-module taiga_local_mem taiga_local_mem.cc SimMem.cc
../test_benches/verilator/taiga_local_mem.sv --top-module taiga_local_mem taiga_local_mem.cc ddr_page.cc SimMem.cc
$(MAKE) -C $@ -f Vtaiga_local_mem.mk
#Run verilator