Core cleanups, fifo optimzations, various area improvements, better glue logic

This commit is contained in:
Eric Matthews 2018-01-16 18:48:03 -08:00
parent 4718e8f85b
commit b41e3fed88
28 changed files with 752 additions and 441 deletions

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
@ -30,7 +30,7 @@ module amo_alu(
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;

View file

@ -91,10 +91,10 @@ module axi_master
end
always_ff @ (posedge clk) begin
if (ls.data_valid)
data_out <= 0;
else if (m_axi.rvalid)
if (m_axi.rvalid)
data_out <= m_axi.rdata;
else
data_out <= 0;
end
//write channel

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
@ -27,8 +27,9 @@ module barrel_shifter (
input logic[XLEN-1:0] shifter_input,
input logic[4:0] shift_amount,
input logic arith,
input logic left_shift,
output logic[XLEN-1:0]shifted_result
output logic[XLEN-1:0] lshifted_result,
output logic[XLEN-1:0] rshifted_result
);
logic[XLEN-1:0] lshifter_input;
@ -55,8 +56,9 @@ module barrel_shifter (
end
//assign lshifted = {<<{shifted}};//if stream operator supported
assign shifted_result = left_shift ? lshifted : shifted[31:0];
//assign shifted_result = left_shift ? lshifted : shifted[31:0];
assign lshifted_result = lshifted;
assign rshifted_result = shifted[31:0];
endmodule

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
@ -95,10 +95,9 @@ module branch_table(
assign ex_entry.prediction = bt.branch_taken;
assign ex_entry.use_ras = bt.is_return_ex;
assign miss_predict = bt.branch_ex && (
(bt.dec_pc != bt.jump_pc && bt.branch_taken) ||
(bt.dec_pc != bt.njump_pc && ~bt.branch_taken));
(bt.branch_taken && bt.dec_pc != bt.jump_pc) ||
(~bt.branch_taken && bt.dec_pc != bt.njump_pc));
assign tag_match = ({if_entry.valid, if_entry.tag} == {(bt.next_pc_valid & bt_on), bt.if_pc[31:32-BTAG_W]});
assign bt.predicted_pc = predicted_pc;

View file

@ -68,24 +68,25 @@ module branch_unit(
logic [31:0] carry;
assign equal = (rs1_sext == rs2_sext);
assign equal = (branch_inputs.rs1 == branch_inputs.rs2);
assign rs1_sext = {branch_inputs.rs1[XLEN-1] & branch_inputs.use_signed, branch_inputs.rs1};
assign rs2_sext = {branch_inputs.rs2[XLEN-1] & branch_inputs.use_signed, branch_inputs.rs2};
assign lessthan = signed'(rs1_sext) < signed'(rs2_sext);
always_comb begin
unique case (fn3_ex) // <-- 010, 011 unused
case (fn3_ex) // <-- 010, 011 unused
BEQ_fn3 : result = equal_ex;
BNE_fn3 : result = ~equal_ex;
BLT_fn3 : result = lessthan_ex;
BGE_fn3 : result = ~lessthan_ex;
BLTU_fn3 : result = lessthan_ex;
BGEU_fn3 : result = ~lessthan_ex;
default : result = 0;
endcase
end
assign bt.branch_taken = (bcomp_ex & result) | jump_ex;
assign bt.branch_taken = (bcomp_ex & result) | jump_ex;
always_comb begin
if (branch_inputs.jal)
@ -107,14 +108,14 @@ module branch_unit(
equal_ex <= equal;
lessthan_ex <= lessthan;
bt.ex_pc <= branch_inputs.dec_pc;
bcomp_ex <= branch_ex.new_request_dec & branch_inputs.branch_compare;
jump_ex <= branch_ex.new_request_dec & (branch_inputs.jal | branch_inputs.jalr);
bcomp_ex <= branch_inputs.branch_compare;
jump_ex <= (branch_inputs.jal | branch_inputs.jalr);
bt.jump_pc <= (branch_inputs.jalr ? branch_inputs.rs1 : branch_inputs.dec_pc) + pc_offset;
bt.njump_pc <= pc_plus_4;
end
assign new_jal_jalr_dec = branch_ex.possible_issue & (branch_inputs.jal | branch_inputs.jalr) & ~branch_inputs.rdx0;
assign new_jal_jalr_dec = (branch_inputs.jal | branch_inputs.jalr) & ~branch_inputs.rdx0;
always_ff @(posedge clk) begin
if (branch_ex.new_request_dec & new_jal_jalr_dec) begin
@ -150,8 +151,7 @@ module branch_unit(
* Output
*********************************/
assign branch_ex.ready = ~done | (done & branch_wb.accepted);
assign branch_wb.rd = rd_ex;
assign branch_wb.rd = rd_ex;
always_ff @(posedge clk) begin
if (rst) begin
@ -164,7 +164,7 @@ module branch_unit(
end
assign branch_wb.done = (done & ~branch_wb.accepted);
assign branch_wb.early_done = new_jal_jalr_dec;
assign branch_wb.early_done = branch_ex.possible_issue & new_jal_jalr_dec;
/*********************************************/

View file

@ -40,7 +40,7 @@ module dbram(
assign data_bram.en = ls.new_request;
assign data_bram.be = ls_inputs.be;
assign data_bram.data_in = ls_inputs.data_in;
assign data_out = data_bram.data_out;
assign data_out = data_bram.data_out & {32{ls.data_valid}};
always_ff @ (posedge clk) begin
if (rst)

View file

@ -40,8 +40,9 @@ module dcache(
input logic is_amo,
input logic [4:0] amo_op,
input logic [31:0] forwarded_data,
input logic use_forwarded_data,
output logic dcache_forward_data,
output logic [2:0] dcache_stage2_fn3,
ls_sub_unit_interface.sub_unit ls
);
@ -63,10 +64,8 @@ module dcache(
logic [DCACHE_SUB_LINE_ADDR_W-1:0] update_word_index;
logic line_complete;
logic reservation;
logic [31:0] stage2_addr;
logic stage2_load;
logic stage2_store;
@ -99,9 +98,9 @@ module dcache(
logic is_target_word;
logic memory_complete;
logic hit_allowed;
logic read_hit_allowed;
logic read_hit_data_valid;
logic address_range_valid;
@ -116,22 +115,40 @@ module dcache(
/*************************************
* 2nd cycle signals
*************************************/
always_ff @ (posedge clk) begin
if(rst)
stage2_use_forwarded_data <= 0;
else if (ls.new_request)
stage2_use_forwarded_data <= use_forwarded_data;
else if (store_complete)
stage2_use_forwarded_data <= 0;
end
always_ff @ (posedge clk) begin
if (ls.new_request) begin
stage2_addr <= ls_inputs.addr;
stage2_be <= ls_inputs.be;
stage2_load <= ls_inputs.load;
stage2_store <= ls_inputs.store;
stage2_data_in <= ls_inputs.data_in;
stage2_use_forwarded_data <= use_forwarded_data;
stage2_lr <= lr;
stage2_is_amo <= is_amo; //excludes lr/sc
stage2_sc <= sc;
stage2_amo_op <= amo_op;
stage2_fn3 <= ls_inputs.fn3;
stage2_data_in <= ls_inputs.data_in;
if (USE_AMO) begin
stage2_lr <= lr;
stage2_is_amo <= is_amo; //excludes lr/sc
stage2_sc <= sc;
stage2_amo_op <= amo_op;
end else begin
stage2_lr <= 0;
stage2_is_amo <= 0; //excludes lr/sc
stage2_sc <= 0;
stage2_amo_op <= 0;
end
end
end
assign dcache_stage2_fn3 = stage2_fn3;
assign dcache_forward_data = stage2_use_forwarded_data;
/*************************************
* General Control Logic
*************************************/
@ -144,6 +161,14 @@ module dcache(
read_hit_allowed <= ls.new_request & ls_inputs.load & dcache_on & ~(lr | is_amo);
end
always_ff @ (posedge clk) begin
if (rst)
read_hit_data_valid <= 0;
else
read_hit_data_valid <= read_hit_allowed;
end
//LR reservation, cleared on exceptions
always_ff @ (posedge clk) begin
if (rst)
@ -187,7 +212,7 @@ module dcache(
else if (l1_response.data_valid)
word_count <= word_count + 1;
end
assign is_target_word = (stage2_addr[DCACHE_SUB_LINE_ADDR_W+1:2] == word_count);
assign is_target_word = (stage2_addr[DCACHE_SUB_LINE_ADDR_W+1:2] == word_count);
always_ff @ (posedge clk) begin
if (rst)
@ -233,7 +258,7 @@ module dcache(
);
assign write_hit_be = stage2_be;// & {4{tag_hit}};
assign write_hit_be = stage2_be & {4{tag_hit}};
//AMO op processing on incoming data
always_ff @ (posedge clk) begin
@ -244,7 +269,9 @@ module dcache(
assign amo_alu_inputs.rs2 = amo_rs2;
assign amo_alu_inputs.op = stage2_amo_op;
amo_alu amo_unit (.*, .result(amo_result));
generate if (USE_AMO)
amo_alu amo_unit (.*, .result(amo_result));
endgenerate
always_comb begin
if (stage2_is_amo & is_target_word)
@ -255,25 +282,18 @@ module dcache(
new_line_data = l1_response.data;
end
assign sc_write_index = stage2_addr[DCACHE_SUB_LINE_ADDR_W+1:2];
assign update_word_index = stage2_sc ? sc_write_index : word_count;
////////////////////////////////////////////////////////
always_comb begin
unique case(stage2_fn3) //<--011, 110, 111, 100, 101 unused
LS_B_fn3 : stage2_forwarded_data = {4{forwarded_data[7:0]}};
LS_H_fn3 : stage2_forwarded_data = {2{forwarded_data[15:0]}};
LS_W_fn3 : stage2_forwarded_data = forwarded_data;
endcase
end
assign stage2_data = stage2_use_forwarded_data ? stage2_forwarded_data : stage2_data_in;
assign stage2_data = stage2_use_forwarded_data ? ls_inputs.data_in : stage2_data_in;
//Data Bank(s)
ddata_bank #(DCACHE_LINES*DCACHE_LINE_W*DCACHE_WAYS) data_bank (
.clk(clk),
.addr_a({tag_hit_way_int, stage2_addr[DCACHE_LINE_ADDR_W+DCACHE_SUB_LINE_ADDR_W+2-1:2]}),
.addr_b({tag_update_way_int, stage2_addr[DCACHE_LINE_ADDR_W+DCACHE_SUB_LINE_ADDR_W+2-1:DCACHE_SUB_LINE_ADDR_W+2], update_word_index}),
.en_a(tag_hit),
.en_a(second_cycle),
.en_b(l1_response.data_valid | (sc_complete & sc_success)),
.be_a(write_hit_be),
.data_in_a(stage2_data),
@ -286,15 +306,15 @@ module dcache(
* Output Muxing
*************************************/
always_ff @ (posedge clk) begin
if (rst | read_miss_complete)
miss_data <= 0;
else if (l1_response.data_valid & is_target_word)
if (l1_response.data_valid & is_target_word)
miss_data <= l1_response.data;
else if (stage2_sc)
else if (sc_complete)
miss_data <= {31'b0, sc_success};
else
miss_data <= 0;
end
assign data_out = miss_data | dbank_data_out;
assign data_out = miss_data | ({32{read_hit_data_valid}} & dbank_data_out);
/*************************************
* Pipeline Advancement
@ -304,26 +324,20 @@ module dcache(
always_ff @ (posedge clk) begin
if (rst)
memory_complete <= 0;
else if (line_complete | (read_hit_allowed & tag_hit) | sc_complete) //read hit OR line fill OR SC complete
memory_complete <= 1;
ls.data_valid <= 0;
else
memory_complete <= 0;
ls.data_valid <= ((l1_response.data_valid & is_target_word) | (read_hit_allowed & tag_hit) | sc_complete);
end
assign ls.data_valid = memory_complete;
//read miss complete includes store conditional complete
always_ff @ (posedge clk) begin
if (rst)
read_miss_complete <= 0;
else if (line_complete | sc_complete) //read hit OR line fill OR SC complete
read_miss_complete <= 1;
else
read_miss_complete <= 0;
read_miss_complete <= line_complete | sc_complete;
end
assign ls.ready = (read_hit_allowed & tag_hit) | store_complete | (read_miss_complete) | idle;
assign ls.ready = (read_hit_allowed & tag_hit) | store_complete | (read_miss_complete) | idle;
always_ff @ (posedge clk) begin
if (rst)

View file

@ -167,7 +167,6 @@ module decode(
assign iq.future_rd_addr = future_rd_addr;
assign iq.data_in.id = id_gen.issue_id;
assign iq.data_in.exception_barrier = ls_inputs.load;
assign iq.new_issue = advance & uses_rd;
assign id_gen.advance = advance & uses_rd;
@ -181,7 +180,7 @@ module decode(
(uses_rs1 && rf_decode.rs1_conflict) ||
(uses_rs2 && rf_decode.rs2_conflict));
assign load_store_forward =((opcode_trim == STORE_T) && last_ls_request_was_load && (rs2_addr == load_rd));
assign load_store_forward = ((opcode_trim == STORE_T) && last_ls_request_was_load && (rs2_addr == load_rd));
assign load_store_operands_ready = !(
(uses_rs1 && rf_decode.rs1_conflict) ||
@ -194,14 +193,14 @@ module decode(
assign new_request[LS_UNIT_ID] = (opcode_trim == LOAD_T || opcode_trim == STORE_T || opcode_trim == AMO_T);
assign new_request[CSR_UNIT_ID] = (opcode_trim == SYSTEM_T);
generate if (USE_MUL)
assign new_request[MUL_UNIT_ID] = mult_div_op & ~fn3[2] ;
assign new_request[MUL_UNIT_ID] = mult_div_op & ~fn3[2];
else
assign new_request[MUL_UNIT_ID] = 0 ;
assign new_request[MUL_UNIT_ID] = 0;
endgenerate
generate if (USE_DIV)
assign new_request[DIV_UNIT_ID] = mult_div_op & fn3[2] ;
assign new_request[DIV_UNIT_ID] = mult_div_op & fn3[2];
else
assign new_request[DIV_UNIT_ID] = 0 ;
assign new_request[DIV_UNIT_ID] = 0;
endgenerate
// assign new_request[CUSTOM_ID_0] = (opcode_trim == CUSTOM_T) && ~ib.data_out.instruction[25] && ~ib.data_out.instruction[26];
@ -329,7 +328,7 @@ module decode(
assign ls_inputs.is_amo = USE_AMO ? (opcode_trim == AMO_T) : 0;
assign ls_inputs.load = (opcode_trim == LOAD_T) || ((opcode_trim == AMO_T) && (ls_inputs.amo != AMO_SC)); //LR and AMO_ops perform a read operation as well
assign ls_inputs.store = (opcode_trim == STORE_T);
assign ls_inputs.load_store_forward = (opcode_trim == STORE_T) && rf_decode.rs2_conflict;
assign ls_inputs.load_store_forward = (opcode_trim == STORE_T) && rf_decode.rs2_conflict;
assign ls_inputs.id = id_gen.issue_id;
always_ff @(posedge clk) begin
@ -420,7 +419,7 @@ module decode(
assign div_inputs.rs1 = rf_decode.rs1_data;
assign div_inputs.rs2 = rf_decode.rs2_data;
assign div_inputs.op = fn3[1:0];
assign div_inputs.reuse_result = prev_div_result_valid && (prev_div_rs1_addr == rs1_addr) && (prev_div_rs2_addr == rs2_addr);
assign div_inputs.reuse_result = 0;//prev_div_result_valid && (prev_div_rs1_addr == rs1_addr) && (prev_div_rs2_addr == rs2_addr);
assign div_inputs.div_zero = (rf_decode.rs2_data == 0);
//----------------------------------------------------------------------------------

View file

@ -69,7 +69,8 @@ module div_unit(
/*********************************
* Input FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH($bits(div_inputs_t)), .FIFO_DEPTH(DIV_INPUT_BUFFER_DEPTH)) div_input_fifo (.fifo(input_fifo), .*);
taiga_fifo #(.DATA_WIDTH($bits(div_inputs_t)), .FIFO_DEPTH(DIV_INPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) div_input_fifo (.fifo(input_fifo), .*);
assign input_fifo.data_in = div_inputs;
assign input_fifo.push = div_ex.new_request_dec;
@ -137,7 +138,8 @@ module div_unit(
/*********************************
* Output FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(DIV_OUTPUT_BUFFER_DEPTH), .BYPASS_REG(0)) output_fifo (.fifo(wb_fifo), .*);
taiga_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(DIV_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) output_fifo (.fifo(wb_fifo), .*);
assign wb_fifo.data_in = div_result_muxed;
assign wb_fifo.push = div_done;

View file

@ -63,6 +63,7 @@ module fetch(
logic [31:0] if_pc;
logic stage1_prediction;
logic space_in_inst_buffer;
logic new_mem_request;
logic fetch_flush;
@ -79,6 +80,8 @@ module fetch(
logic pc_valid;
logic[6:0] opcode;
logic[4:0] opcode_trimmed;
logic[2:0] fn3;
logic csr_imm_op;
@ -101,11 +104,9 @@ module fetch(
always_ff @(posedge clk) begin
if (rst) begin
if_pc <= RESET_VEC;
stage1_prediction <= 0;
end
else if (new_mem_request | flush) begin
if_pc <= {next_pc[31:2], 2'b0};
stage1_prediction <= bt.use_prediction & bt.prediction;
end
end
@ -142,15 +143,14 @@ module fetch(
if(rst)
stage2_valid <= 0;
if (new_mem_request)
stage2_valid <= new_mem_request;
else if (new_issue)
stage2_valid <= 1;
else if (new_issue | fetch_flush)
stage2_valid <= 0;
end
always_ff @(posedge clk) begin
if (new_mem_request) begin
stage2_phys_address <= tlb.physical_address;
stage2_prediction <= stage1_prediction;//not taken if no valid prediction
stage2_cache_access <= cache_access;
end
end
@ -166,8 +166,9 @@ module fetch(
assign mem_ready = fetch_sub[ICACHE_ID].ready;
assign fetch_flush = (bt.flush | exception);
assign new_mem_request = pc_valid & tlb.complete & ~fetch_flush & ((stage2_valid & ~ib.early_full) | (~stage2_valid & ~ib.full)) & mem_ready;
assign space_in_inst_buffer = (stage2_valid & ~ib.early_full) | (~stage2_valid & ~ib.full);
assign new_mem_request = pc_valid & tlb.complete & ~fetch_flush & space_in_inst_buffer & mem_ready;
assign fetch_sub[BRAM_ID].new_request = new_mem_request & bram_access;
assign fetch_sub[ICACHE_ID].new_request = new_mem_request & cache_access;
@ -182,7 +183,7 @@ module fetch(
generate if (USE_I_SCRATCH_MEM)
ibram i_bram (.*, .fetch_sub(fetch_sub[BRAM_ID]));
else begin
assign fetch_sub[BRAM_ID].ready = 1;
assign fetch_sub[BRAM_ID].ready = 1;
assign fetch_sub[BRAM_ID].data_valid = 0;
assign fetch_sub[BRAM_ID].data_out = 0;
end
@ -190,7 +191,7 @@ module fetch(
generate if (USE_ICACHE)
icache i_cache (.*, .fetch_sub(fetch_sub[ICACHE_ID]));
else begin
assign fetch_sub[ICACHE_ID].ready = 1;
assign fetch_sub[ICACHE_ID].ready = 1;
assign fetch_sub[ICACHE_ID].data_valid = 0;
assign fetch_sub[ICACHE_ID].data_out = 0;
end
@ -200,7 +201,7 @@ module fetch(
always_ff @(posedge clk) begin
if (rst)
delayed_flush <= 0;
else if ((bt.flush | exception) & stage2_cache_access & ~fetch_sub[ICACHE_ID].data_valid)//& ~fetch_sub[ICACHE_ID].ready
else if ((bt.flush | exception) & stage2_valid & stage2_cache_access & ~fetch_sub[ICACHE_ID].data_valid)//& ~fetch_sub[ICACHE_ID].ready
delayed_flush <= 1;
else if (fetch_sub[ICACHE_ID].data_valid)
delayed_flush <= 0;
@ -211,24 +212,25 @@ module fetch(
assign ib.push = new_issue;
assign ib.flush = bt.flush;
assign ib.data_in.instruction = fetch_sub[BRAM_ID].data_out | fetch_sub[ICACHE_ID].data_out;
assign ib.data_in.instruction = ({32{~stage2_cache_access}} & fetch_sub[BRAM_ID].data_out) |
({32{stage2_cache_access}} & fetch_sub[ICACHE_ID].data_out);
assign ib.data_in.pc = stage2_phys_address;
assign ib.data_in.prediction = stage2_prediction;
//Early decode
assign fn3 =ib.data_in.instruction[14:12];
assign opcode = ib.data_in.instruction[6:0];
assign opcode_trimmed = opcode[6:2];
assign csr_imm_op = (opcode == SYSTEM) && fn3[2];
assign sys_op = (opcode == SYSTEM) && (fn3 == 0);
assign csr_imm_op = (opcode_trimmed == SYSTEM_T) && fn3[2];
assign sys_op = (opcode_trimmed == SYSTEM_T) && (fn3 == 0);
assign jal_jalr_x0 = ((opcode == JAL) || (opcode == JALR)) && (ib.data_in.instruction[11:7] == 0);
assign jal_jalr_x0 = ((opcode_trimmed == JAL_T) || (opcode_trimmed == JALR_T)) && (ib.data_in.instruction[11:7] == 0);//rd is x0
assign ib.data_in.uses_rs1 = !((opcode == LUI) || (opcode == AUIPC) || (opcode == JAL) || (opcode == FENCE) || csr_imm_op || sys_op);
assign ib.data_in.uses_rs2 = ((opcode == BRANCH) || (opcode == STORE) || (opcode == ARITH) || (opcode == AMO));
assign ib.data_in.uses_rd = !((opcode == BRANCH) || (opcode == STORE) || (opcode == FENCE) || sys_op || jal_jalr_x0);
//TODO: function for set comparison
assign ib.data_in.uses_rs1 = !((opcode_trimmed == LUI_T) || (opcode_trimmed == AUIPC_T) || (opcode_trimmed == JAL_T) || (opcode_trimmed == FENCE_T) || csr_imm_op || sys_op);
assign ib.data_in.uses_rs2 = ((opcode_trimmed == BRANCH_T) || (opcode_trimmed == STORE_T) || (opcode_trimmed == ARITH_T) || (opcode_trimmed == AMO_T) || (opcode_trimmed == CUSTOM_T));
assign ib.data_in.uses_rd = !((opcode_trimmed == BRANCH_T) || (opcode_trimmed == STORE_T) || (opcode_trimmed == FENCE_T) || sys_op || jal_jalr_x0);
endmodule

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
@ -41,12 +41,13 @@ module icache(
logic [ICACHE_WAYS-1:0] tag_update_way;
logic [$clog2(ICACHE_LINE_W)-1:0] word_count;
logic is_target_word;
logic line_complete;
logic [31:0] data_out [ICACHE_WAYS-1:0];
logic [31:0] miss_data;
logic miss;
logic miss_data_ready;
logic second_cycle;
logic idle;
@ -73,13 +74,6 @@ module icache(
second_cycle <= fetch_sub.new_request;
end
always_ff @ (posedge clk) begin
if (rst | memory_complete)
miss <= 0;
else if (second_cycle)
miss <= ~tag_hit;
end
always_ff @ (posedge clk) begin
if (rst)
tag_update <= 0;
@ -162,18 +156,32 @@ module icache(
/*************************************
* Output Muxing
*************************************/
assign is_target_word = (fetch_sub.stage2_addr[ICACHE_SUB_LINE_ADDR_W+1:2] == word_count);
always_ff @ (posedge clk) begin
if (l1_response.data_valid && fetch_sub.stage2_addr[ICACHE_SUB_LINE_ADDR_W+1:2] == word_count)
if (l1_response.data_valid & is_target_word)
miss_data <= l1_response.data;
else
miss_data <= 0;
end
always_ff @ (posedge clk) begin
if (rst)
miss_data_ready <= 0;
else
miss_data_ready <= l1_response.data_valid & is_target_word;
end
always_comb begin
fetch_sub.data_out = miss_data & {32{miss}};
fetch_sub.data_out = miss_data;//zero if not a miss
for (int i =0; i < ICACHE_WAYS; i++) begin
fetch_sub.data_out = fetch_sub.data_out | (data_out[i] & {32{tag_hit_way[i]}});
end
end
assign fetch_sub.data_valid = miss_data_ready | (hit_allowed & tag_hit);
/*************************************
* Pipeline Advancement
*************************************/
@ -182,14 +190,10 @@ module icache(
always_ff @ (posedge clk) begin
if (rst)
memory_complete <= 0;
else if (fetch_sub.new_request | memory_complete)
memory_complete <= 0;
else if (line_complete) //read miss OR write through complete
memory_complete <= 1;
else
memory_complete <= line_complete;
end
assign fetch_sub.data_valid = memory_complete | (hit_allowed & tag_hit);
assign fetch_sub.ready = (hit_allowed & tag_hit) | memory_complete | idle;//~(second_cycle & ~tag_hit) & ~miss;
always_ff @ (posedge clk) begin

View file

@ -30,7 +30,7 @@ module id_generator (
id_generator_interface.generator id_gen
);
logic inuse [0:INFLIGHT_QUEUE_DEPTH-1];
logic [0:INFLIGHT_QUEUE_DEPTH-1] inuse;
always_ff @ (posedge clk) begin
for (int i=0; i <INFLIGHT_QUEUE_DEPTH; i=i+1) begin
@ -53,14 +53,8 @@ module id_generator (
end
end
always_comb begin
id_gen.id_avaliable = id_gen.complete;
for (int i=0; i <INFLIGHT_QUEUE_DEPTH; i=i+1) begin
if(~inuse[i])
id_gen.id_avaliable = 1;
end
end
//Instruction complete or at least one inuse bit is not set
assign id_gen.id_avaliable = id_gen.complete | ~(&inuse);
endmodule

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
@ -31,51 +31,34 @@ module instruction_buffer
instruction_buffer_interface.buffer ib
);
logic[$bits(instruction_buffer_packet)-1:0] shift_reg[FETCH_BUFFER_DEPTH-1:0];
logic[$bits(instruction_buffer_packet)-1:0] shift_reg_in;
instruction_buffer_packet shift_reg_out;
logic [$clog2(FETCH_BUFFER_DEPTH)-1:0] write_index;
logic [$clog2(FETCH_BUFFER_DEPTH)-1:0] read_index;
logic count_v [FETCH_BUFFER_DEPTH:0];
logic buffer_reset;
fifo_interface #(.DATA_WIDTH($bits(instruction_buffer_packet))) ib_fifo();
//implementation
////////////////////////////////////////////////////
//Control signals
assign buffer_reset = rst | ib.flush;
assign ib_fifo.push = ib.push;
assign ib_fifo.pop = ib.pop;
assign ib_fifo.data_in = ib.data_in;
assign ib.data_out = ib_fifo.data_out;
assign ib.valid = ib_fifo.valid;
assign ib.full = ib_fifo.full;
assign ib.early_full = ib_fifo.early_full;
taiga_fifo #(
.DATA_WIDTH($bits(instruction_buffer_packet)),
.FIFO_DEPTH(FETCH_BUFFER_DEPTH),
.FIFO_TYPE(LUTRAM_FIFO)
) ib_fifo_block (.fifo(ib_fifo), .rst(buffer_reset), .*);
////////////////////////////////////////////////////
//Assertions
always_ff @ (posedge clk) begin
if (rst | ib.flush) begin
write_index <= 0;
read_index <= 0;
end
else begin
read_index <= read_index + ib.pop;
write_index <= write_index + ib.push;
end
assert (!(~rst & ib.flush & (ib.push | ib.pop))) else $error("ib push/pop during flush");
end
assign ib.early_full = count_v[FETCH_BUFFER_DEPTH-1] | count_v[FETCH_BUFFER_DEPTH];
assign ib.full = count_v[FETCH_BUFFER_DEPTH];
assign ib.valid = ~count_v[0];
always_ff @ (posedge clk) begin
if (rst | ib.flush) begin
count_v[0] <= 1;
for (int i = 1; i <= FETCH_BUFFER_DEPTH; i++) count_v[i] <= 0;
end
else if (ib.push & ~ib.pop)
count_v <= {count_v[FETCH_BUFFER_DEPTH-1:0], 1'b0};
else if (~ib.push & ib.pop)
count_v <= {1'b0, count_v[FETCH_BUFFER_DEPTH:1]};
end
always_ff @ (posedge clk) begin
if (ib.push)
shift_reg[write_index] <= ib.data_in;
end
assign ib.data_out = shift_reg[read_index];
endmodule
endmodule

View file

@ -67,11 +67,12 @@ endinterface
interface func_unit_ex_interface;
logic new_request_dec;
logic possible_issue;
logic new_request;
logic ready;
modport decode (input ready, output new_request_dec, new_request);
modport unit (output ready, input new_request_dec, new_request);
modport decode (input ready, output possible_issue, new_request_dec, new_request);
modport unit (output ready, input possible_issue, new_request_dec, new_request);
endinterface
interface ras_interface;
@ -87,7 +88,7 @@ interface ras_interface;
endinterface
interface unit_writeback_interface;
logic done ;
logic done;
logic early_done;
logic accepted;
logic [XLEN-1:0] rd;
@ -153,17 +154,20 @@ endinterface
interface inflight_queue_interface;
logic[INFLIGHT_QUEUE_DEPTH-1:0] pop;
logic[INFLIGHT_QUEUE_DEPTH-1:0] shift_pop;
logic[INFLIGHT_QUEUE_DEPTH:0] pop;
logic[INFLIGHT_QUEUE_DEPTH:0] shift_pop;
logic new_issue;
inflight_queue_packet data_in;
inflight_queue_packet[INFLIGHT_QUEUE_DEPTH-1:0] data_out;
logic [INFLIGHT_QUEUE_DEPTH-1:0] valid;
logic [4:0] future_rd_addr;
inflight_queue_packet[INFLIGHT_QUEUE_DEPTH:0] data_out;
logic [4:0] wb_rd_addr;
instruction_id_t wb_id;
logic [INFLIGHT_QUEUE_DEPTH:0] valid;
modport queue (input pop, data_in, new_issue, output data_out, shift_pop, valid);
modport decode (output data_in, new_issue);
modport wb (input data_in, shift_pop, valid, data_out, output pop);
modport queue (input pop, data_in, new_issue, future_rd_addr, wb_id, output data_out, wb_rd_addr, shift_pop, valid);
modport decode (output data_in, future_rd_addr, new_issue);
modport wb (input data_in, future_rd_addr, shift_pop, valid, data_out, wb_rd_addr, output pop, wb_id);
endinterface
@ -199,7 +203,7 @@ interface instruction_buffer_interface;
endinterface
interface fifo_interface #(parameter DATA_WIDTH = 32);//#(parameter type data_type = logic[31:0]);
interface fifo_interface #(parameter DATA_WIDTH = 42);//#(parameter type data_type = logic[31:0]);
logic push;
logic pop;
logic [DATA_WIDTH-1:0] data_in;

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import taiga_config::*;
import taiga_types::*;
import l2_config_and_types::*;
@ -34,15 +34,36 @@ module l1_arbiter
output sc_complete,
output sc_success,
l1_arbiter_request_interface.arb l1_request[3:0],
l1_arbiter_return_interface.arb l1_response[3:0]
l1_arbiter_request_interface.arb l1_request[L1_CONNECTIONS-1:0],
l1_arbiter_return_interface.arb l1_response[L1_CONNECTIONS-1:0]
);
l2_request_t[3:0] l2_requests;
l2_request_t[L1_CONNECTIONS-1:0] l2_requests;
logic [L1_CONNECTIONS-1:0] requests;
logic [L1_CONNECTIONS-1:0] acks;
logic push_ready;
logic request_exists;
//////////////////////////////////////
genvar i;
generate
for (i=0; i <L1_CONNECTIONS; i++) begin
assign requests[i] = l1_request[i].request;
assign l1_request[i].ack = acks[i];
end
endgenerate
generate
if (USE_DCACHE && USE_DTAG_INVALIDATIONS)
assign l2.inv_ack = l1_response[L1_DCACHE_ID].inv_ack;
else
assign l2.inv_ack = l2.inv_valid;
endgenerate
assign l2.inv_ack = l1_response[L1_DCACHE_ID].inv_ack;
assign l2.rd_data_ack = l2.rd_data_valid;
assign sc_complete = l2.con_valid;
assign sc_success = l2.con_result;
@ -50,57 +71,105 @@ module l1_arbiter
//arbiter can pop address FIFO at a different rate than the data FIFO, so check that both have space.
assign push_ready = ~l2.request_full & ~l2.data_full;
assign l1_request[L1_DCACHE_ID].ack = l1_request[L1_DCACHE_ID].request & push_ready;
assign l1_request[L1_DMMU_ID].ack = l1_request[L1_DMMU_ID].request & push_ready & ~l1_request[L1_DCACHE_ID].request;
assign l1_request[L1_ICACHE_ID].ack = l1_request[L1_ICACHE_ID].request & push_ready & ~l1_request[L1_DCACHE_ID].request & ~l1_request[L1_DMMU_ID].request;
assign l1_request[L1_IMMU_ID].ack = l1_request[L1_IMMU_ID].request & push_ready & ~l1_request[L1_DCACHE_ID].request & ~l1_request[L1_DMMU_ID].request & ~l1_request[L1_ICACHE_ID].request;
assign l2.request_push = push_ready & (l1_request[L1_DCACHE_ID].request | l1_request[L1_DMMU_ID].request | l1_request[L1_ICACHE_ID].request | l1_request[L1_IMMU_ID].request);
assign l2.wr_data_push = push_ready & l1_request[L1_DCACHE_ID].request & ~l1_request[L1_DCACHE_ID].rnw; //Assumes data cache has highest priority
//priority 0-to-n
logic busy;
always_comb begin
l2_requests[L1_DCACHE_ID].addr = l1_request[L1_DCACHE_ID].addr[31:2];
l2_requests[L1_DCACHE_ID].rnw = l1_request[L1_DCACHE_ID].rnw;
l2_requests[L1_DCACHE_ID].be = l1_request[L1_DCACHE_ID].be;
l2_requests[L1_DCACHE_ID].is_amo = l1_request[L1_DCACHE_ID].is_amo;
l2_requests[L1_DCACHE_ID].amo_type_or_burst_size = l1_request[L1_DCACHE_ID].is_amo ? l1_request[L1_DCACHE_ID].amo : l1_request[L1_DCACHE_ID].size;
l2_requests[L1_DCACHE_ID].sub_id = L1_DCACHE_ID;
request_exists = l1_request[0].request;
acks[0] = l1_request[0].request & push_ready;
busy = l1_request[0].request;
for (int i=1; i <L1_CONNECTIONS; i++) begin
request_exists |= requests[i];
acks[i] = requests[i] & push_ready & ~busy;
busy |= requests[i];
end
end
assign l2.request_push = push_ready & request_exists;
// assign l2_requests[L1_DCACHE_ID] = l1_request[L1_DCACHE_ID].to_l2(L1_DCACHE_ID);
assign l2_requests[L1_DMMU_ID] = l1_request[L1_DMMU_ID].to_l2(L1_DMMU_ID);
assign l2_requests[L1_ICACHE_ID] = l1_request[L1_ICACHE_ID].to_l2(L1_ICACHE_ID);
assign l2_requests[L1_IMMU_ID] = l1_request[L1_IMMU_ID].to_l2(L1_IMMU_ID);
generate
if (USE_DCACHE) begin
assign l2.wr_data_push = push_ready & l1_request[L1_DCACHE_ID].request & ~l1_request[L1_DCACHE_ID].rnw; //Assumes data cache has highest priority
assign l2.wr_data = l1_request[L1_DCACHE_ID].data;
end
else begin
assign l2.wr_data_push = 0;
assign l2.wr_data = 0;
end
if (USE_DTAG_INVALIDATIONS) begin
assign l1_response[L1_DCACHE_ID].inv_addr = l2.inv_addr;
assign l1_response[L1_DCACHE_ID].inv_valid = l2.inv_valid;
end
else begin
assign l1_response[L1_DCACHE_ID].inv_addr = 0;
assign l1_response[L1_DCACHE_ID].inv_valid = 0;
end
endgenerate
generate if (USE_DCACHE) begin
always_comb begin
l2_requests[L1_DCACHE_ID].addr = l1_request[L1_DCACHE_ID].addr[31:2];
l2_requests[L1_DCACHE_ID].rnw = l1_request[L1_DCACHE_ID].rnw;
l2_requests[L1_DCACHE_ID].be = l1_request[L1_DCACHE_ID].be;
l2_requests[L1_DCACHE_ID].is_amo = l1_request[L1_DCACHE_ID].is_amo;
l2_requests[L1_DCACHE_ID].amo_type_or_burst_size = l1_request[L1_DCACHE_ID].is_amo ? l1_request[L1_DCACHE_ID].amo : l1_request[L1_DCACHE_ID].size;
l2_requests[L1_DCACHE_ID].sub_id = L1_DCACHE_ID;
end
end
endgenerate
generate if (USE_ICACHE) begin
always_comb begin
l2_requests[L1_ICACHE_ID].addr = l1_request[L1_ICACHE_ID].addr[31:2];
l2_requests[L1_ICACHE_ID].rnw = l1_request[L1_ICACHE_ID].rnw;
l2_requests[L1_ICACHE_ID].be = l1_request[L1_ICACHE_ID].be;
l2_requests[L1_ICACHE_ID].is_amo = l1_request[L1_ICACHE_ID].is_amo;
l2_requests[L1_ICACHE_ID].amo_type_or_burst_size = l1_request[L1_ICACHE_ID].size;
l2_requests[L1_ICACHE_ID].sub_id = L1_ICACHE_ID;
end
end
endgenerate
generate if (USE_MMU) begin
always_comb begin
l2_requests[L1_DMMU_ID].addr = l1_request[L1_DMMU_ID].addr[31:2];
l2_requests[L1_DMMU_ID].rnw = l1_request[L1_DMMU_ID].rnw;
l2_requests[L1_DMMU_ID].be = l1_request[L1_DMMU_ID].be;
l2_requests[L1_DMMU_ID].is_amo = l1_request[L1_DMMU_ID].is_amo;
l2_requests[L1_DMMU_ID].amo_type_or_burst_size = l1_request[L1_DMMU_ID].size;
l2_requests[L1_DMMU_ID].sub_id = L1_DMMU_ID;
l2_requests[L1_IMMU_ID].addr = l1_request[L1_IMMU_ID].addr[31:2];
l2_requests[L1_IMMU_ID].rnw = l1_request[L1_IMMU_ID].rnw;
l2_requests[L1_IMMU_ID].be = l1_request[L1_IMMU_ID].be;
l2_requests[L1_IMMU_ID].is_amo = l1_request[L1_IMMU_ID].is_amo;
l2_requests[L1_IMMU_ID].amo_type_or_burst_size = l1_request[L1_IMMU_ID].size;
l2_requests[L1_IMMU_ID].sub_id = L1_IMMU_ID;
end
end
endgenerate
// generate
// for (i=1; i <L1_CONNECTIONS; i++) begin
// assign l2_requests[i] = l1_request[i].to_l2(i);
// end
// endgenerate
always_comb begin
if (l1_request[L1_DCACHE_ID].request)
l2.request = l2_requests[L1_DCACHE_ID];
else if (l1_request[L1_DMMU_ID].request)
l2.request = l2_requests[L1_DMMU_ID];
else if (l1_request[L1_ICACHE_ID].request)
l2.request = l2_requests[L1_ICACHE_ID];
else
l2.request = l2_requests[L1_IMMU_ID];
l2.request = l2_requests[L1_CONNECTIONS-1];
for (int i = L1_CONNECTIONS-2; i >=0; i--) begin
if (requests[i])
l2.request = l2_requests[i];
end
end
assign l2.wr_data = l1_request[L1_DCACHE_ID].data;
generate
for (i=0; i <L1_CONNECTIONS; i++) begin
assign l1_response[i].data = l2.rd_data;
assign l1_response[i].data_valid = l2.rd_data_valid && (l2.rd_sub_id == i);
end
endgenerate
assign l1_response[L1_DCACHE_ID].data = l2.rd_data;
assign l1_response[L1_DMMU_ID].data = l2.rd_data;
assign l1_response[L1_ICACHE_ID].data = l2.rd_data;
assign l1_response[L1_IMMU_ID].data = l2.rd_data;
assign l1_response[L1_DCACHE_ID].data_valid = l2.rd_data_valid && (l2.rd_sub_id == L1_DCACHE_ID);
assign l1_response[L1_DMMU_ID].data_valid = l2.rd_data_valid && (l2.rd_sub_id == L1_DMMU_ID);
assign l1_response[L1_ICACHE_ID].data_valid = l2.rd_data_valid && (l2.rd_sub_id == L1_ICACHE_ID);
assign l1_response[L1_IMMU_ID].data_valid = l2.rd_data_valid && (l2.rd_sub_id == L1_IMMU_ID);
assign l1_response[L1_DCACHE_ID].inv_addr = l2.inv_addr;
assign l1_response[L1_DCACHE_ID].inv_valid = l2.inv_valid;
endmodule

View file

@ -88,7 +88,7 @@ module load_store_unit (
logic [NUM_SUB_UNITS-1:0] sub_unit_address_match;
logic dcache_forward_data;
logic dcache_stage2_fn3;
logic [2:0] dcache_stage2_fn3;
//AMO support
//LR -- invalidates line if tag hit
@ -128,6 +128,7 @@ module load_store_unit (
assign units_ready = &unit_ready;
assign data_valid = |unit_data_valid;
//Without cache to others (BRAM/BUS) forwarding no checking would be required for load_store_forwarding
assign issue_request = ((stage1.load_store_forward & (data_valid | ~load_attributes.valid)) | (~stage1.load_store_forward)) & input_fifo.valid & units_ready & ~wb_fifo.early_full;
assign load_complete = data_valid;
@ -154,13 +155,14 @@ module load_store_unit (
/*********************************
* Input FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH($bits(load_store_inputs_t)), .FIFO_DEPTH(LS_INPUT_BUFFER_DEPTH)) ls_input_fifo (.fifo(input_fifo), .*);
taiga_fifo #(.DATA_WIDTH($bits(load_store_inputs_t)), .FIFO_DEPTH(LS_INPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) ls_input_fifo (.fifo(input_fifo), .*);
assign input_fifo.data_in = ls_inputs;
assign input_fifo.push = ls_ex.new_request_dec;
assign ls_ex.ready = ~input_fifo.full;
assign input_fifo.pop = issue_request;
assign inorder = input_fifo.valid;
assign inorder = 0;//input_fifo.valid;
assign stage1 = input_fifo.data_out;
/*********************************
* TLB interface
@ -230,22 +232,24 @@ module load_store_unit (
assign d_inputs.be = be;
assign d_inputs.fn3 = stage1.fn3;
always_comb begin
unique case(dcache_forward_data ? dcache_stage2_fn3 : stage1.fn3) //<--011, 110, 111, 100, 101 unused
LS_B_fn3 : d_inputs.data_in = {4{stage1_raw_data[7:0]}};
LS_H_fn3 : d_inputs.data_in = {2{stage1_raw_data[15:0]}};
LS_W_fn3 : d_inputs.data_in = stage1_raw_data;
case(dcache_forward_data ? dcache_stage2_fn3[1:0] : stage1.fn3[1:0]) //<--011, 110, 111, 100, 101 unused
LS_H_fn3[1:0] : d_inputs.data_in = {2{stage1_raw_data[15:0]}};
LS_W_fn3[1:0] : d_inputs.data_in = stage1_raw_data;
default : d_inputs.data_in = {4{stage1_raw_data[7:0]}}; //LS_B_fn3
endcase
end
/*********************************
* Load attributes FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH($bits(load_attributes_t)), .FIFO_DEPTH(ATTRIBUTES_DEPTH)) attributes_fifo (.fifo(load_attributes), .*);
assign load_attributes.pop = load_complete;
assign load_attributes.push = issue_request & stage1.load;
assign load_attributes.data_in = load_attributes_in;
taiga_fifo #(.DATA_WIDTH($bits(load_attributes_t)), .FIFO_DEPTH(ATTRIBUTES_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) attributes_fifo (.fifo(load_attributes), .*);
assign load_attributes_in.fn3 = stage1.fn3;
assign load_attributes_in.byte_addr = virtual_address[1:0];
assign load_attributes.data_in = load_attributes_in;
assign load_attributes.push = issue_request & stage1.load;
assign load_attributes.pop = load_complete;
assign stage2_attr = load_attributes.data_out;
@ -287,7 +291,7 @@ module load_store_unit (
//Cache
generate if (USE_DCACHE)
dcache data_cache (.clk(clk), .rst(rst), .ls_inputs(d_inputs), .ls(ls_sub[DCACHE_ID]), .is_amo(is_amo), .use_forwarded_data( stage1.load_store_forward), .forwarded_data(most_recent_load), .data_out(unit_data_array[DCACHE_ID]), .*);
dcache data_cache (.clk(clk), .rst(rst), .ls_inputs(d_inputs), .ls(ls_sub[DCACHE_ID]), .is_amo(is_amo), .use_forwarded_data(stage1.load_store_forward), .data_out(unit_data_array[DCACHE_ID]), .*);
endgenerate
/*************************************
* Output Muxing
@ -313,7 +317,7 @@ module load_store_unit (
//Sign extending
always_comb begin
unique case(stage2_attr.fn3)
case(stage2_attr.fn3)
LS_B_fn3 : final_load_data = 32'(signed'(aligned_load_data[7:0]));
LS_H_fn3 : final_load_data = 32'(signed'(aligned_load_data[15:0]));
LS_W_fn3 : final_load_data = aligned_load_data;
@ -322,6 +326,7 @@ module load_store_unit (
L_HU_fn3 : final_load_data = 32'(unsigned'(aligned_load_data[15:0]));
//unused 110
//unused 111
default : final_load_data = aligned_load_data;
endcase
end
@ -333,7 +338,8 @@ module load_store_unit (
/*********************************
* Output FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(LS_OUTPUT_BUFFER_DEPTH), .BYPASS_REG(0)) output_fifo (.fifo(wb_fifo), .*);
taiga_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(LS_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) output_fifo (.fifo(wb_fifo), .*);
assign wb_fifo.data_in = final_load_data;
assign wb_fifo.push = load_complete;

View file

@ -1,104 +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>
*/
import taiga_config::*;
import taiga_types::*;
/*
* LUT RAM FIFO implementation. Not underflow/overflow safe.
* Intended for small FIFO depths.
*/
module lutram_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4)
(
input logic clk,
input logic rst,
fifo_interface.structure fifo
);
logic [DATA_WIDTH-1:0] lut_ram[FIFO_DEPTH-1:0];
logic[$clog2(FIFO_DEPTH)-1:0] read_index;
logic[$clog2(FIFO_DEPTH)-1:0] read_index_new;
logic[$clog2(FIFO_DEPTH)-1:0] write_index;
logic[$clog2(FIFO_DEPTH)-1:0] write_index_new;
logic two_plus;
////////////////////////////////////////////////////////
//implementation
assign fifo.data_out = lut_ram[read_index];
assign read_index_new = read_index + fifo.pop;
assign write_index_new = write_index + fifo.push;
always_ff @ (posedge clk) begin
if (rst) begin
read_index <= 0;
write_index <= 0;
end
else begin
read_index <= read_index_new;
write_index <= write_index_new;
end
end
always_ff @ (posedge clk) begin
if (rst | (fifo.pop & ~fifo.push & ~fifo.full))
fifo.early_full <= 0;
else if (fifo.push & ~fifo.pop)
fifo.early_full <= (write_index+2 == read_index);
end
always_ff @ (posedge clk) begin
if (rst | (fifo.pop & ~fifo.push))
fifo.full <= 0;
else if (fifo.push & ~fifo.pop)
fifo.full <= (write_index_new == read_index);
end
always_ff @ (posedge clk) begin
if (rst | (fifo.pop & ~fifo.push && (read_index_new == write_index)))
fifo.valid <= 0;
else if (fifo.push)
fifo.valid <= 1;
end
always_ff @ (posedge clk) begin
if (rst | (fifo.pop & ~fifo.push && (read_index+2 == write_index)))
two_plus <= 0;
else if (fifo.valid & fifo.push & ~fifo.pop)
two_plus <= 1;
end
always_ff @ (posedge clk) begin
if (fifo.push)
lut_ram[write_index] <= fifo.data_in;
end
//pushing, or more than one, or at least one and not popping
assign fifo.early_valid = fifo.push | (two_plus) | (fifo.valid & ~fifo.pop);
endmodule

View file

@ -79,7 +79,9 @@ module mul_unit(
/*********************************
* Output FIFO
*********************************/
lutram_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(MUL_OUTPUT_BUFFER_DEPTH), .BYPASS_REG(0)) output_fifo (.fifo(wb_fifo), .*);
taiga_fifo #(
.DATA_WIDTH(XLEN), .FIFO_DEPTH(MUL_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) output_fifo (.fifo(wb_fifo), .*);
assign wb_fifo.data_in = result;
assign wb_fifo.push = mul_done;

View file

@ -4,7 +4,7 @@
* 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
@ -19,7 +19,7 @@
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
module one_hot_to_integer
#(
parameter C_WIDTH = 32

View file

@ -39,7 +39,7 @@ module register_file(
logic rs2_feedforward;
logic in_use_match;
logic [$clog2(INFLIGHT_QUEUE_DEPTH)-1:0] in_use_by_id_r;
logic [$clog2(INFLIGHT_QUEUE_DEPTH)-1:0] in_use_by_id;
//////////////////////////////////////////
//Assign zero to r0 and initialize all registers to zero
@ -64,8 +64,10 @@ module register_file(
always_ff @ (posedge clk) begin
if (rst)
inuse[i] <= 0;
else if ((rf_decode.instruction_issued && rf_decode.future_rd_addr == i) || (rf_wb.valid_write && (rf_wb.rd_addr == i) && in_use_match))
inuse[i] <= rf_decode.instruction_issued;
else if (rf_decode.future_rd_addr == i && rf_decode.instruction_issued)
inuse[i] <= 1;
else if(rf_wb.rd_addr == i && rf_wb.valid_write && in_use_match)
inuse[i] <= 0;
end
end
endgenerate
@ -74,11 +76,9 @@ module register_file(
if (rf_decode.instruction_issued)
in_use_by[rf_decode.future_rd_addr] <= rf_decode.id;
end
//always_ff @ (posedge clk) begin
assign in_use_by_id_r = in_use_by[rf_wb.rd_addr];
//end
assign in_use_match = (in_use_by_id_r == rf_wb.id);
assign in_use_by_id = in_use_by[rf_wb.rd_addr];
assign in_use_match = (in_use_by_id == rf_wb.id);
assign rs1_feedforward = (rf_decode.rs1_addr == rf_wb.rd_addr) && rf_wb.valid_write && in_use_match;
assign rs2_feedforward = (rf_decode.rs2_addr == rf_wb.rd_addr) && rf_wb.valid_write && in_use_match;

View file

@ -43,8 +43,8 @@ module taiga (
);
l1_arbiter_request_interface l1_request[3:0]();
l1_arbiter_return_interface l1_response[3:0]();
l1_arbiter_request_interface l1_request[L1_CONNECTIONS-1:0]();
l1_arbiter_return_interface l1_response[L1_CONNECTIONS-1:0]();
logic sc_complete;
logic sc_success;
@ -154,6 +154,14 @@ module taiga (
*************************************/
branch_unit branch_unit_block (.*, .branch_wb(unit_wb[BRANCH_UNIT_ID].unit));
alu_unit alu_unit_block (.*, .alu_wb(unit_wb[ALU_UNIT_ID].unit));
// genvar i;
// generate
// for (i = 0; i < 5; i++) begin
// alu_unit single_cycle_accelerators (.*, .alu_ex(single_accel), .alu_wb(unit_wb[ACCEL+i].unit));
// end
// endgenerate
//
load_store_unit load_store_unit_block (.*, .dcache_on(1'b1), .clear_reservation(1'b0), .tlb(dtlb), .ls_wb(unit_wb[LS_UNIT_ID].unit), .l1_request(l1_request[L1_DCACHE_ID]), .l1_response(l1_response[L1_DCACHE_ID]));
generate if (USE_MMU) begin
tlb_lut_ram #(DTLB_WAYS, DTLB_DEPTH) d_tlb (.*, .tlb(dtlb), .mmu(dmmu));

View file

@ -29,17 +29,18 @@ package taiga_config;
parameter CPU_ID = 0;//32 bit value
parameter bit[31:0] RESET_VEC = 32'h80000000;
parameter bit[31:0] RESET_VEC = 32'h00000000;
parameter ASIDLEN = 7;//pid
parameter PAGE_ADDR_W = 12;
parameter TIMER_W = 48; //32 days @ 100MHz
parameter TIMER_W = 33; //32 days @ 100MHz
parameter USE_DIV = 1;
parameter USE_MUL = 1;
parameter USE_DIV = 1;
parameter USE_VARIABLE_LATENCY_DIV = 0;
parameter USE_AMO = 0;
parameter NUM_WB_UNITS = 6;
parameter WB_UNITS_WIDTH = $clog2(NUM_WB_UNITS);
@ -49,30 +50,34 @@ package taiga_config;
CSR_UNIT_ID = 2,
LS_UNIT_ID = 3,
MUL_UNIT_ID = 4,
DIV_UNIT_ID = 5
DIV_UNIT_ID = 5,
CUSTOM_ID_0 = 6,
CUSTOM_ID_1 = 7,
CUSTOM_ID_2 = 8,
CUSTOM_ID_3 = 9
} unit_ids;
parameter INFLIGHT_QUEUE_DEPTH = 8;
parameter INFLIGHT_QUEUE_DEPTH = 4;
parameter FETCH_BUFFER_DEPTH = 4;
parameter LS_INPUT_BUFFER_DEPTH=4;
parameter LS_OUTPUT_BUFFER_DEPTH=2;
parameter LS_INPUT_BUFFER_DEPTH = 4;
parameter LS_OUTPUT_BUFFER_DEPTH = 4;
parameter MUL_CYCLES = 1;
parameter MUL_OUTPUT_BUFFER_DEPTH=2;
parameter MUL_OUTPUT_BUFFER_DEPTH = 2;
parameter DIV_INPUT_BUFFER_DEPTH=2;
parameter DIV_OUTPUT_BUFFER_DEPTH=2;
parameter DIV_INPUT_BUFFER_DEPTH = 2;
parameter DIV_OUTPUT_BUFFER_DEPTH = 2;
//Address space
parameter USE_I_SCRATCH_MEM = 1;
parameter USE_D_SCRATCH_MEM = 1;
parameter SCRATCH_ADDR_L = 32'h80000000;
parameter SCRATCH_ADDR_H = 32'h8000FFFF;
parameter SCRATCH_BIT_CHECK = 16;
parameter SCRATCH_ADDR_L = 32'h00000000;
parameter SCRATCH_ADDR_H = 32'h0000FFFF;
parameter SCRATCH_BIT_CHECK = 4;
parameter MEMORY_ADDR_L = 32'h20000000;
parameter MEMORY_ADDR_H = 32'h3FFFFFFF;
parameter MEMORY_ADDR_L = 32'h40000000;
parameter MEMORY_ADDR_H = 32'h4FFFFFFF;
parameter MEMORY_BIT_CHECK = 4;
parameter BUS_ADDR_L = 32'h60000000;
@ -88,21 +93,23 @@ package taiga_config;
//Caches
//Size in bytes: (DCACHE_LINES * DCACHE_WAYS * DCACHE_LINE_W * 4)
parameter USE_DCACHE = 1;
parameter DCACHE_LINES = 128;
parameter USE_DCACHE = 0;
parameter DCACHE_LINES = 512;
parameter DCACHE_WAYS = 2;
parameter DCACHE_LINE_ADDR_W = $clog2(DCACHE_LINES);
parameter DCACHE_LINE_W = 8; //In words
parameter DCACHE_SUB_LINE_ADDR_W = $clog2(DCACHE_LINE_W);
parameter DCACHE_TAG_W = ADDR_W - DCACHE_LINE_ADDR_W - DCACHE_SUB_LINE_ADDR_W - 2;
parameter USE_DTAG_INVALIDATIONS = 0;
parameter DTLB_WAYS = 2;
parameter DTLB_DEPTH = 32;
//Size in bytes: (ICACHE_LINES * ICACHE_WAYS * ICACHE_LINE_W * 4)
//For optimal BRAM packing lines should not be less than 512
parameter USE_ICACHE = 1;
parameter USE_ICACHE = 0;
parameter ICACHE_LINES = 128;
parameter ICACHE_WAYS = 2;
parameter ICACHE_LINE_ADDR_W = $clog2(ICACHE_LINES);
@ -110,18 +117,17 @@ package taiga_config;
parameter ICACHE_SUB_LINE_ADDR_W = $clog2(ICACHE_LINE_W);
parameter ICACHE_TAG_W = ADDR_W - ICACHE_LINE_ADDR_W - ICACHE_SUB_LINE_ADDR_W - 2;
parameter USE_BRANCH_PREDICTOR = 0;
parameter BRANCH_TABLE_ENTRIES = 1024;
parameter USE_BRANCH_PREDICTOR = 1;
parameter BRANCH_TABLE_ENTRIES = 512;
parameter RAS_DEPTH = 8;
parameter ITLB_WAYS = 2;
parameter ITLB_DEPTH = 32;
typedef enum bit [1:0] {
L1_DCACHE_ID = 2'd0,
L1_DMMU_ID = 2'd1,
L1_ICACHE_ID = 2'd2,
L1_IMMU_ID = 2'd3
} l1_connection_id;
parameter L1_CONNECTIONS = USE_ICACHE + USE_DCACHE + USE_MMU*2;
parameter L1_DCACHE_ID = 0;
parameter L1_DMMU_ID = USE_MMU;
parameter L1_ICACHE_ID = USE_MMU + USE_DCACHE;
parameter L1_IMMU_ID = USE_MMU + USE_DCACHE + USE_ICACHE;
endpackage

169
core/taiga_fifo.sv Normal file
View file

@ -0,0 +1,169 @@
/*
* 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::*;
/*
* FIFOs Not underflow/overflow safe.
* Intended for small FIFO depths.
*/
module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, parameter fifo_type_t FIFO_TYPE = NON_MUXED_INPUT_FIFO)
(
input logic clk,
input logic rst,
fifo_interface.structure fifo
);
logic[DATA_WIDTH-1:0] lut_ram[FIFO_DEPTH-1:0];
logic[DATA_WIDTH-1:0] shift_reg[FIFO_DEPTH-1:0];
logic[DATA_WIDTH-1:0] shift_reg_new[FIFO_DEPTH-1:0];
logic[$clog2(FIFO_DEPTH)-1:0] write_index;
logic[$clog2(FIFO_DEPTH)-1:0] read_index;
logic two_plus;
logic[FIFO_DEPTH:0] valid_chain;
genvar i;
//implementation
////////////////////////////////////////////////////
//Occupancy Tracking
always_ff @ (posedge clk) begin
if (rst)
valid_chain <= 1;
else if (fifo.push & ~fifo.pop)
valid_chain <= {valid_chain[FIFO_DEPTH-1:0], 1'b0};
else if (fifo.pop & ~fifo.push)
valid_chain <= {1'b0, valid_chain[FIFO_DEPTH:1]};
end
assign fifo.empty = valid_chain[0];
assign fifo.valid = ~valid_chain[0];
assign fifo.full = valid_chain[FIFO_DEPTH];
assign fifo.early_full = valid_chain[FIFO_DEPTH-1] | valid_chain[FIFO_DEPTH];
//pushing, or more than one, or at least one and not popping
assign two_plus = ~valid_chain[0] & ~valid_chain[1];
assign fifo.early_valid = fifo.push | (two_plus) | (fifo.valid & ~fifo.pop);
////////////////////////////////////////////////////
//LUT-RAM version
generate if (FIFO_TYPE == LUTRAM_FIFO) begin
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (rst) begin
read_index <= '0;
write_index <= '0;
end
else begin
read_index <= read_index + fifo.pop;
write_index <= write_index + fifo.push;
end
end
assign fifo.data_out = lut_ram[read_index];
always_ff @ (posedge clk) begin
if (fifo.push)
lut_ram[write_index] <= fifo.data_in;
end
end
endgenerate
////////////////////////////////////////////////////
//SRL version
generate if (FIFO_TYPE == NON_MUXED_INPUT_FIFO) begin
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (rst)
read_index <= 0;
else if ((fifo.valid & fifo.push) | (two_plus & fifo.pop))
read_index <= read_index + fifo.push - fifo.pop;
end
assign fifo.data_out = shift_reg[read_index];
always_ff @ (posedge clk) begin
if (fifo.push)
shift_reg[0] <= fifo.data_in;
end
for (i=1 ; i < FIFO_DEPTH; i++) begin : shift_reg_gen
always_ff @ (posedge clk) begin
if (fifo.push)
shift_reg[i] <= shift_reg[i-1];
end
end
end
endgenerate
////////////////////////////////////////////////////
//Non-muxed output version
generate if (FIFO_TYPE == NON_MUXED_OUTPUT_FIFO) begin
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (rst)
write_index <= 0;
else
write_index <= write_index + fifo.push - fifo.pop;
end
assign fifo.data_out = shift_reg[0];
for (i=0 ; i <FIFO_DEPTH; i++) begin : new_reg_non_muxed_gen
always_comb begin
if (fifo.push && write_index == i)
shift_reg_new[i] = fifo.data_in;
else
shift_reg_new[i] = shift_reg[i];
end
end
always_ff @ (posedge clk) begin
shift_reg[FIFO_DEPTH-1] <= shift_reg_new[FIFO_DEPTH-1];
end
for (i=0 ; i < FIFO_DEPTH-1; i++) begin : shift_reg_non_muxed_gen
always_ff @ (posedge clk) begin
if (fifo.pop)
shift_reg[i] <= shift_reg_new[i+1];
else
shift_reg[i] <= shift_reg_new[i];
end
end
end
endgenerate
////////////////////////////////////////////////////
//Assertions
always_ff @ (posedge clk) begin
assert (!(~rst & valid_chain[FIFO_DEPTH] & fifo.push)) else $error("fifo overflow");
assert (!(~rst & valid_chain[0] & fifo.pop)) else $error("fifo underflow");
end
endmodule

View file

@ -39,6 +39,23 @@ package taiga_types;
//end of RV32I
} opcodes_t;
typedef enum bit [4:0] {
LUI_T = 5'b01101,
AUIPC_T = 5'b00101,
JAL_T = 5'b11011,
JALR_T = 5'b11001,
BRANCH_T = 5'b11000,
LOAD_T = 5'b00000,
STORE_T = 5'b01000,
ARITH_IMM_T = 5'b00100,
ARITH_T = 5'b01100,//includes mul/div
FENCE_T = 5'b00011,
AMO_T = 5'b01011,
SYSTEM_T = 5'b11100,
//end of RV32I
CUSTOM_T = 5'b11110
} opcodes_trimmed_t;
typedef enum bit [2:0] {
ADD_SUB_fn3 = 3'b000,
SLL_fn3 = 3'b001,
@ -214,17 +231,23 @@ package taiga_types;
typedef enum bit [1:0] {
ALU_SLT = 2'b00,
ALU_LOGIC = 2'b01,
ALU_SHIFTR = 2'b01,
ALU_SHIFT =2'b10,
ALU_ADD_SUB = 2'b11
ALU_LOGIC = 2'b11
} alu_op_t;
typedef enum bit [1:0] {
ALU_XOR = 2'b00,
ALU_OR = 2'b01,
ALU_AND = 2'b10,
ALU_ADD_SUB = 2'b11
} alu_logicop_t;
typedef logic[$clog2(INFLIGHT_QUEUE_DEPTH)-1:0] instruction_id_t;
typedef struct packed{
logic [WB_UNITS_WIDTH-1:0] unit_id;
logic [4:0] rd_addr;
instruction_id_t id;
} inflight_queue_packet;
@ -241,12 +264,11 @@ package taiga_types;
typedef struct packed{
logic [XLEN-1:0] in1;
logic [XLEN-1:0] in2;
logic [2:0] fn3;
logic add;
logic subtract;
logic arith;
logic left_shift;
logic [XLEN-1:0] shifter_in;
logic sltu;
logic [1:0] logic_op;
logic [1:0] op;
}alu_inputs_t;
@ -345,6 +367,12 @@ package taiga_types;
logic [31:0] data_in;
} data_access_shared_inputs_t;
typedef enum {
LUTRAM_FIFO,
NON_MUXED_INPUT_FIFO,
NON_MUXED_OUTPUT_FIFO
} fifo_type_t;
endpackage

View file

@ -30,6 +30,7 @@ module xilinx_byte_enable_ram #(
)
(
input logic clk,
input logic[$clog2(LINES)-1:0] addr_a,
input logic en_a,
input logic[XLEN/8-1:0] be_a,
@ -61,9 +62,7 @@ module xilinx_byte_enable_ram #(
end
always_ff @(posedge clk) begin
if (~en_a)
data_out_a <= 0;
else
if (en_a)
data_out_a <= ram[addr_a];
end
@ -77,9 +76,7 @@ module xilinx_byte_enable_ram #(
end
always_ff @(posedge clk) begin
if (~en_b)
data_out_b <= 0;
else
if (en_b)
data_out_b <= ram[addr_b];
end

View file

@ -229,21 +229,24 @@ module taiga_wrapper (
design_2 infra(.*);
l2_arbiter l2_arb (.*, .request(l2));
axi_to_arb l2_to_mem (.*, .l2(mem));
generate
if (USE_MMU || USE_ICACHE || USE_DCACHE) begin
l2_arbiter l2_arb (.*, .request(l2));
axi_to_arb l2_to_mem (.*, .l2(mem));
end
endgenerate
arm proc(.*);
byte_en_BRAM #(8192) inst_data_ram (
byte_en_BRAM #(8192*4, "/home/ematthew/Research/RISCV/software2/riscv-tools/riscv-tests/benchmarks/dhrystone.riscv.hw_init", 1) inst_data_ram (
.clk(clk),
.addr_a(instruction_bram.addr[$clog2(8192)- 1:0]),
.addr_a(instruction_bram.addr[$clog2(8192*4)- 1:0]),
.en_a(instruction_bram.en),
.be_a(instruction_bram.be),
.data_in_a(instruction_bram.data_in),
.data_out_a(instruction_bram.data_out),
.addr_b(data_bram.addr[$clog2(8192)- 1:0]),
.addr_b(data_bram.addr[$clog2(8192*4)- 1:0]),
.en_b(data_bram.en),
.be_b(data_bram.be),
.data_in_b(data_bram.data_in),

View file

@ -27,7 +27,7 @@ import taiga_config::*;
import taiga_types::*;
import l2_config_and_types::*;
`define MEMORY_FILE "/home/ematthew/taiga/examples/zedboard/dhrystone.riscv.sim_init"
`define MEMORY_FILE "/home/ematthew/Research/RISCV/software2/riscv-tools/riscv-tests/benchmarks/sqrt.riscv.sim_init"
`define UART_LOG "/home/ematthew/uart.log"
module taiga_tb ( );
@ -181,6 +181,7 @@ module taiga_tb ( );
integer output_file;
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;
@ -195,6 +196,9 @@ module taiga_tb ( );
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
@ -202,6 +206,9 @@ module taiga_tb ( );
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]));
@ -231,7 +238,7 @@ module taiga_tb ( );
end
do_reset();
#1200000;
#3600000;
$fclose(output_file);
$finish;
end

View file

@ -15,15 +15,15 @@
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="939960000fs"></ZoomStartTime>
<ZoomEndTime time="950860001fs"></ZoomEndTime>
<Cursor1Time time="943640000fs"></Cursor1Time>
<ZoomStartTime time="4143000000fs"></ZoomStartTime>
<ZoomEndTime time="4445500001fs"></ZoomEndTime>
<Cursor1Time time="4293000000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="233"></NameColumnWidth>
<ValueColumnWidth column_width="90"></ValueColumnWidth>
<NameColumnWidth column_width="297"></NameColumnWidth>
<ValueColumnWidth column_width="87"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="158" />
<WVObjectSize size="183" />
<wvobject type="logic" fp_name="/taiga_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
@ -95,6 +95,10 @@
<obj_property name="ElementShortName">cache_access</obj_property>
<obj_property name="ObjectShortName">cache_access</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/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="logic" fp_name="/taiga_tb/uut/fetch_block/bram_access">
<obj_property name="ElementShortName">bram_access</obj_property>
<obj_property name="ObjectShortName">bram_access</obj_property>
@ -221,6 +225,18 @@
<obj_property name="ElementShortName">advance</obj_property>
<obj_property name="ObjectShortName">advance</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/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_tb/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_tb/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_tb/uut/write_back_mux/inorder">
<obj_property name="ElementShortName">inorder</obj_property>
<obj_property name="ObjectShortName">inorder</obj_property>
@ -272,15 +288,51 @@
<obj_property name="ElementShortName">register[0:31][31:0]</obj_property>
<obj_property name="ObjectShortName">register[0:31][31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/rd_addr">
<obj_property name="ElementShortName">rd_addr[4:0]</obj_property>
<obj_property name="ObjectShortName">rd_addr[4:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/rd_addr_r">
<obj_property name="ElementShortName">rd_addr_r[4:0]</obj_property>
<obj_property name="ObjectShortName">rd_addr_r[4:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/write_back_mux/selected_unit_done">
<obj_property name="ElementShortName">selected_unit_done</obj_property>
<obj_property name="ObjectShortName">selected_unit_done</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/register_file_block/inuse">
<obj_property name="ElementShortName">inuse[0:31]</obj_property>
<obj_property name="ObjectShortName">inuse[0:31]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/rf_wb/valid_write">
<obj_property name="ElementShortName">valid_write</obj_property>
<obj_property name="ObjectShortName">valid_write</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/rf_wb/rd_addr">
<obj_property name="ElementShortName">rd_addr[4:0]</obj_property>
<obj_property name="ObjectShortName">rd_addr[4:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/register_file_block/inorder">
<obj_property name="ElementShortName">inorder</obj_property>
<obj_property name="ObjectShortName">inorder</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/register_file_block/in_use_match">
<obj_property name="ElementShortName">in_use_match</obj_property>
<obj_property name="ObjectShortName">in_use_match</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/register_file_block/in_use_by">
<obj_property name="ElementShortName">in_use_by[0:31][1:0]</obj_property>
<obj_property name="ObjectShortName">in_use_by[0:31][1:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/write_back_mux/entry_found">
<obj_property name="ElementShortName">entry_found</obj_property>
<obj_property name="ObjectShortName">entry_found</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/done">
<obj_property name="ElementShortName">done[5:0]</obj_property>
<obj_property name="ObjectShortName">done[5:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/early_done">
<obj_property name="ElementShortName">early_done[5:0]</obj_property>
<obj_property name="ObjectShortName">early_done[5:0]</obj_property>
@ -290,17 +342,13 @@
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/inst_queue/shift_reg">
<obj_property name="ElementShortName">shift_reg[3:0][9:0]</obj_property>
<obj_property name="ObjectShortName">shift_reg[3:0][9:0]</obj_property>
<obj_property name="ElementShortName">shift_reg[4:0][4:0]</obj_property>
<obj_property name="ObjectShortName">shift_reg[4:0][4:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/unit_id">
<obj_property name="ElementShortName">unit_id[2:0]</obj_property>
<obj_property name="ObjectShortName">unit_id[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/write_back_mux/iq_index">
<obj_property name="ElementShortName">iq_index[1:0]</obj_property>
<obj_property name="ObjectShortName">iq_index[1:0]</obj_property>
</wvobject>
<wvobject fp_name="divider3000" type="divider">
<obj_property name="label">LS Unit</obj_property>
<obj_property name="DisplayName">label</obj_property>
@ -313,6 +361,14 @@
<obj_property name="ElementShortName">ls_inputs</obj_property>
<obj_property name="ObjectShortName">ls_inputs</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/ls_input_fifo/read_index">
<obj_property name="ElementShortName">read_index[2:0]</obj_property>
<obj_property name="ObjectShortName">read_index[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/ls_input_fifo/valid_chain">
<obj_property name="ElementShortName">valid_chain[4:0]</obj_property>
<obj_property name="ObjectShortName">valid_chain[4:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/stage1">
<obj_property name="ElementShortName">stage1</obj_property>
<obj_property name="ObjectShortName">stage1</obj_property>
@ -332,6 +388,30 @@
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_valid">
<obj_property name="ElementShortName">unit_data_valid[2:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_valid[2:0]</obj_property>
<obj_property name="CustomSignalColor">#FFD700</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_valid[2]">
<obj_property name="ElementShortName">[2]</obj_property>
<obj_property name="ObjectShortName">[2]</obj_property>
<obj_property name="CustomSignalColor">#FFD700</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_valid[1]">
<obj_property name="ElementShortName">[1]</obj_property>
<obj_property name="ObjectShortName">[1]</obj_property>
<obj_property name="CustomSignalColor">#FFD700</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_valid[0]">
<obj_property name="ElementShortName">[0]</obj_property>
<obj_property name="ObjectShortName">[0]</obj_property>
<obj_property name="CustomSignalColor">#FFD700</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk6.d_bram /data_bram/en">
<obj_property name="ElementShortName">en</obj_property>
<obj_property name="ObjectShortName">en</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/issue_request">
<obj_property name="ElementShortName">issue_request</obj_property>
@ -341,6 +421,14 @@
<obj_property name="ElementShortName">load_complete</obj_property>
<obj_property name="ObjectShortName">load_complete</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_valid">
<obj_property name="ElementShortName">unit_data_valid[2:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_valid[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/unit_data_array">
<obj_property name="ElementShortName">unit_data_array[2:0][31:0]</obj_property>
<obj_property name="ObjectShortName">unit_data_array[2:0][31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/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>
@ -353,29 +441,53 @@
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\ls_sub[2] /data_valid">
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /ls/data_valid">
<obj_property name="ElementShortName">data_valid</obj_property>
<obj_property name="ObjectShortName">data_valid</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\ls_sub[2] /ready">
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /ls/ready">
<obj_property name="ElementShortName">ready</obj_property>
<obj_property name="ObjectShortName">ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\ls_sub[2] /new_request">
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /ls/new_request">
<obj_property name="ElementShortName">new_request</obj_property>
<obj_property name="ObjectShortName">new_request</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/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 type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/wb_fifo/full">
<obj_property name="ElementShortName">full</obj_property>
<obj_property name="ObjectShortName">full</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/load_attributes/data_out">
<obj_property name="ElementShortName">data_out[4:0]</obj_property>
<obj_property name="ObjectShortName">data_out[4:0]</obj_property>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /second_cycle">
<obj_property name="ElementShortName">second_cycle</obj_property>
<obj_property name="ObjectShortName">second_cycle</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /request">
<obj_property name="ElementShortName">request</obj_property>
<obj_property name="ObjectShortName">request</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /tag_hit">
<obj_property name="ElementShortName">tag_hit</obj_property>
<obj_property name="ObjectShortName">tag_hit</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /line_complete">
<obj_property name="ElementShortName">line_complete</obj_property>
<obj_property name="ObjectShortName">line_complete</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /read_miss_complete">
<obj_property name="ElementShortName">read_miss_complete</obj_property>
<obj_property name="ObjectShortName">read_miss_complete</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /store_complete">
<obj_property name="ElementShortName">store_complete</obj_property>
<obj_property name="ObjectShortName">store_complete</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /memory_complete">
<obj_property name="ElementShortName">memory_complete</obj_property>
<obj_property name="ObjectShortName">memory_complete</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/\genblk8.data_cache /idle">
<obj_property name="ElementShortName">idle</obj_property>
<obj_property name="ObjectShortName">idle</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/load_attributes/valid">
<obj_property name="ElementShortName">valid</obj_property>
@ -385,10 +497,33 @@
<obj_property name="label">L2</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/\genblk1.arb /requests">
<obj_property name="ElementShortName">requests[3:0]</obj_property>
<obj_property name="ObjectShortName">requests[3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/\genblk1.arb /acks">
<obj_property name="ElementShortName">acks[3:0]</obj_property>
<obj_property name="ObjectShortName">acks[3:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/\genblk1.arb /push_ready">
<obj_property name="ElementShortName">push_ready</obj_property>
<obj_property name="ObjectShortName">push_ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/\genblk1.arb /request_exists">
<obj_property name="ElementShortName">request_exists</obj_property>
<obj_property name="ObjectShortName">request_exists</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/\genblk1.arb /busy">
<obj_property name="ElementShortName">busy</obj_property>
<obj_property name="ObjectShortName">busy</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/\genblk1.arb /l2_requests">
<obj_property name="ElementShortName">l2_requests[3:0]</obj_property>
<obj_property name="ObjectShortName">l2_requests[3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/l2_arb/\request[0] /request">
<obj_property name="ElementShortName">request</obj_property>
<obj_property name="ObjectShortName">request</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/l2_arb/\request[0] /request_push">
<obj_property name="ElementShortName">request_push</obj_property>
@ -397,28 +532,10 @@
<wvobject type="array" fp_name="/taiga_tb/l2_arb/requests">
<obj_property name="ElementShortName">requests[1:0]</obj_property>
<obj_property name="ObjectShortName">requests[1:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/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_tb/l2_arb/\genblk1[0].input_fifo /\genblk1.genblk1.write_index ">
<obj_property name="ElementShortName">\genblk1.genblk1.write_index [1:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.write_index [1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/l2_arb/\genblk1[0].input_fifo /\genblk1.genblk1.read_index ">
<obj_property name="ElementShortName">\genblk1.genblk1.read_index [1:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.read_index [1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/l2_arb/\genblk1[0].input_fifo /\genblk1.genblk1.lut_ram ">
<obj_property name="ElementShortName">\genblk1.genblk1.lut_ram [3:0][42:0]</obj_property>
<obj_property name="ObjectShortName">\genblk1.genblk1.lut_ram [3:0][42:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/l2_arb/arb/requests">
<obj_property name="ElementShortName">requests[1:0]</obj_property>
<obj_property name="ObjectShortName">requests[1:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/l2_arb/arb/grantee_i">
<obj_property name="ElementShortName">grantee_i[0:0]</obj_property>