misc changes and fixes

This commit is contained in:
Eric Matthews 2018-05-15 14:26:53 -07:00
parent 9e66c2a331
commit 4c2c0915b3
29 changed files with 780 additions and 644 deletions

View file

@ -31,66 +31,45 @@ module alu_unit(
input alu_inputs_t alu_inputs
);
logic [XLEN:0] add_sub_result;
logic [XLEN-1:0] logic_result;
logic [XLEN-1:0] result;
logic [XLEN-1:0] result2;
logic[XLEN:0] add_sub_result;
logic[XLEN-1:0] logic_result;
logic[XLEN-1:0] shifter_result;
logic done;
logic[XLEN:0] add_sub_1;
logic[XLEN:0] add_sub_2;
logic[XLEN-1:0] shifter_resultl;
logic[XLEN-1:0] shifter_resultr;
assign add_sub_1 = {(alu_inputs.in1[XLEN-1] & ~alu_inputs.sltu), alu_inputs.in1};
assign add_sub_2 = {(alu_inputs.in2[XLEN-1] & ~alu_inputs.sltu), alu_inputs.in2};
//Add sub op
//assign add_sub_result = alu_inputs.subtract ? (add_sub_1 - add_sub_2) : (add_sub_1 + add_sub_2);
//implementation
////////////////////////////////////////////////////
assign add_sub_result = alu_inputs.subtract ? alu_inputs.in1 - alu_inputs.in2 : alu_inputs.in1 + alu_inputs.in2;
always_comb begin
case (alu_inputs.logic_op) // <-- 010, 011 unused
ALU_XOR : add_sub_result = add_sub_1 ^ add_sub_2;
ALU_OR : add_sub_result = add_sub_1 | add_sub_2;
ALU_AND : add_sub_result = add_sub_1 & add_sub_2;
ALU_ADD_SUB : add_sub_result = alu_inputs.subtract ? add_sub_1 - add_sub_2 : add_sub_1 + add_sub_2;
case (alu_inputs.fn3[1:0])
XOR_fn3 : logic_result = alu_inputs.in1[XLEN-1:0] ^ alu_inputs.in2[XLEN-1:0];
OR_fn3 : logic_result = alu_inputs.in1[XLEN-1:0] | alu_inputs.in2[XLEN-1:0];
default : logic_result = alu_inputs.in1[XLEN-1:0] & alu_inputs.in2[XLEN-1:0];
endcase
end
//alu_logic_ops_and_adder logic_and_adder (
// .op_type(alu_inputs.op[1:0]),
// .sub(alu_inputs.subtract),
// .A(add_sub_1),
// .B(add_sub_2),
// .result(add_sub_result)
// );
//Barrel Shifter (initial bit flipping occurs in decode/issue stage)
barrel_shifter shifter (
.shifter_input(alu_inputs.shifter_in),
.shifter_input(alu_inputs.in1[XLEN-1:0]),
.shift_amount(alu_inputs.in2[4:0]),
.arith(alu_inputs.arith),
.lshifted_result(shifter_resultl),
.rshifted_result(shifter_resultr)
.lshift(alu_inputs.lshift),
.shifted_result(shifter_result)
);
//Result mux
always_comb begin
case (alu_inputs.op)
ALU_SLT : result = {31'b0, add_sub_result[XLEN]};
ALU_SHIFTR : result = shifter_resultr;
ALU_SHIFT : result = shifter_resultl;
ALU_ADD_SUB : result = add_sub_result[XLEN-1:0];
ALU_ADD_SUB : alu_wb.rd = add_sub_result[XLEN-1:0];
ALU_LOGIC : alu_wb.rd = logic_result;
ALU_SLT : alu_wb.rd = {31'b0, add_sub_result[XLEN]};
ALU_SHIFT : alu_wb.rd = shifter_result;
endcase
end
//Issue/write-back handshaking
////////////////////////////////////////////////////
assign alu_ex.ready = ~done | (done & alu_wb.accepted);
assign alu_wb.rd = result;
always_ff @(posedge clk) begin
if (rst) begin
done <= 0;
@ -101,8 +80,8 @@ module alu_unit(
end
end
assign alu_wb.done = (done & ~alu_wb.accepted);
assign alu_wb.early_done = alu_ex.possible_issue;
assign alu_wb.done_next_cycle = (done & ~alu_wb.accepted);
assign alu_wb.done_on_first_cycle = 1;
////////////////////////////////////////////////////
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::*;
import l2_config_and_types::*;
@ -234,7 +234,7 @@ module axi_to_arb
on_last_burst <= 0;
else if (axi_bvalid)
on_last_burst <= 0;
else if ((~write_in_progress && write_reference_burst_count == 0) || write_in_progress && write_reference_burst_count == write_burst_count)
else if ((~write_in_progress && write_reference_burst_count == 0) || (write_in_progress && write_reference_burst_count == write_burst_count))
on_last_burst <= 1;
end

View file

@ -27,38 +27,68 @@ module barrel_shifter (
input logic[XLEN-1:0] shifter_input,
input logic[4:0] shift_amount,
input logic arith,
output logic[XLEN-1:0] lshifted_result,
output logic[XLEN-1:0] rshifted_result
input logic lshift,
output logic[XLEN-1:0] shifted_result
);
logic[XLEN-1:0] lshifter_input;
logic[XLEN-1:0] shifter_in;
logic[XLEN-1:0] lshifted;
logic[XLEN:0] shifted;
//Bit flipping shared shifter
// always_comb begin
// for (int i =0; i < 32; i++) begin
// lshifter_input[i] = shifter_input[31-i];
// end
//end
//assign shifter_in = left_shift ? lshifter_input : shifter_input;
assign shifted = signed'({arith,shifter_input}) >>> shift_amount;
logic[XLEN-1:0] shifted;
logic[XLEN-1:0] shiftx16, shiftx4, shiftx1;
logic[XLEN*2-1:0] shiftx16_padded, shiftx4_padded;
//Flip left shift input
always_comb begin
for (int i =0; i < 32; i++) begin
lshifted[i] = shifted[31-i];
lshifter_input[i] = shifter_input[31-i];
end
end
//assign lshifted = {<<{shifted}};//if stream operator supported
assign shifter_in = lshift ? lshifter_input : shifter_input;
//Bit flipping shared shifter
//left shift occurs in decode logic
//assign shifted_result = left_shift ? lshifted : shifted[31:0];
assign lshifted_result = lshifted;
assign rshifted_result = shifted[31:0];
always_comb begin
case ({shift_amount[4],lshift})
0: shiftx16 = shifter_input;
1: shiftx16 = lshifter_input;
2: shiftx16 = {{16{arith}}, shifter_input[15:0]};
3: shiftx16 = {{16{arith}}, lshifter_input[15:0]};
endcase
end
assign shiftx16_padded = {{32{arith}}, shiftx16};
always_comb begin
case (shift_amount[3:2])
0: shiftx4 <= shiftx16_padded[31:0];
1: foreach (shiftx4[i]) shiftx4[i] <= shiftx16_padded[i+4];
2: foreach (shiftx4[i]) shiftx4[i] <= shiftx16_padded[i+8];
3: foreach (shiftx4[i]) shiftx4[i] <= shiftx16_padded[i+12];
endcase
end
assign shiftx4_padded = {{32{arith}}, shiftx4};
always_comb begin
case (shift_amount[1:0])
0: shiftx1 <= shiftx4_padded[31:0];
1: foreach (shiftx1[i]) shiftx1[i] <= shiftx4_padded[i+1];
2: foreach (shiftx1[i]) shiftx1[i] <= shiftx4_padded[i+2];
3: foreach (shiftx1[i]) shiftx1[i] <= shiftx4_padded[i+3];
endcase
end
//Flip left shift output
always_comb begin
for (int i =0; i < 32; i++) begin
lshifted[i] = shiftx1[31-i];
end
end
assign shifted_result = lshift ? lshifted : shiftx1;
//assign shifted_result = lshift ? signed'({arith,shifter_input} <<< shift_amount) : signed'({arith,shifter_input} >>> shift_amount);
endmodule

108
core/binary_occupancy.sv Normal file
View file

@ -0,0 +1,108 @@
/*
* 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::*;
module binary_occupancy #(parameter DEPTH = 4)
(
input logic clk,
input logic rst,
input logic push,
input logic pop,
output logic early_full,
output logic full,
output logic empty,
output logic valid,
output logic early_valid,
output logic two_plus
);
logic[$clog2(DEPTH)-1:0] count;
//Occupancy Tracking
always_ff @ (posedge clk) begin
if (rst)
count <= 0;
else if (push & ~pop)
count <= count + 1;
else if (pop & ~push)
count <= count - 1;
end
always_ff @ (posedge clk) begin
if (rst)
valid <= 0;
else if (push)
valid <= 1;
else if (pop && (count == 1))
valid <= 0;
end
always_ff @ (posedge clk) begin
if (rst)
full <= 0;
else if ((push & ~pop) && (count == DEPTH-1))
full <= 1;
else if (pop)
full <= 0;
end
always_ff @ (posedge clk) begin
if (rst)
early_full <= 0;
else if ((push & ~pop) && (count == DEPTH-2))
early_full <= 1;
else if (pop && (count == DEPTH-1))
early_full <= 0;
end
always_ff @ (posedge clk) begin
if (rst)
two_plus <= 0;
else if ((push & ~pop) && (count >= 1))
two_plus <= 1;
else if (pop && (count == 2))
two_plus <= 0;
end
assign empty = ~valid;//(count == 0);
//assign valid = //(count != 0);
//assign full = (count == (DEPTH-1));
//assign early_full = (count == (DEPTH-2)) & push & ~pop;
//pushing, or more than one, or at least one and not popping
//assign two_plus = (count > 1);
assign early_valid = push | (two_plus) | (valid & ~pop);
////////////////////////////////////////////////////
//Assertions
always_ff @ (posedge clk) begin
assert (!(~rst & full & push)) else $error("overflow");
assert (!(~rst & empty & pop)) else $error("underflow");
end
endmodule

View file

@ -53,19 +53,18 @@ module branch_table(
logic [31:0] miss_predict_ret;
logic [31:0] miss_predict_jalr;
logic miss_predict;
logic miss_predict2;
logic tag_match;
/////////////////////////////////////////
logic bt_on;
initial begin
for(int i=0; i<BRANCH_TABLE_ENTRIES; i=i+1) begin
//foreach(branch_table_tag_ram[i]) begin
branch_table_tag_ram[i] = 0;
branch_table_addr_ram[i] = 0;
branch_table_addr_ram[i] = RESET_VEC;
end
end
@ -99,19 +98,13 @@ module branch_table(
(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 tag_match = ({if_entry.valid, if_entry.tag} == {1'b1, bt.if_pc[31:32-BTAG_W]});
assign bt.predicted_pc = predicted_pc;
assign bt.prediction = if_entry.prediction;
always_ff @(posedge clk) begin
if (rst)
bt_on <= 0;
else if (bt.branch_ex)
bt_on <= 1;
end
generate if (USE_BRANCH_PREDICTOR) begin
assign bt.use_prediction = bt_on & tag_match;
assign bt.use_prediction = tag_match;
assign bt.flush = miss_predict;
end else begin
assign bt.use_prediction = 0;
@ -129,8 +122,6 @@ module branch_table(
end
end
always_ff @(posedge clk) begin
if (rst) begin
miss_predict_ret <= 0;

View file

@ -53,8 +53,8 @@ module branch_unit(
logic [31:0] ret_count;
logic [31:0] br_count;
logic [32:0] rs1_sext;
logic [32:0] rs2_sext;
logic signed [32:0] rs1_sext;
logic signed [32:0] rs2_sext;
logic jump_ex;
logic bcomp_ex;
@ -67,7 +67,6 @@ module branch_unit(
logic [31:0] select_new_carry;
logic [31:0] carry;
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};
@ -75,14 +74,13 @@ module branch_unit(
assign lessthan = signed'(rs1_sext) < signed'(rs2_sext);
always_comb begin
case (fn3_ex) // <-- 010, 011 unused
unique 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
@ -104,7 +102,11 @@ module branch_unit(
assign bt.branch_ex = branch_ex.new_request;
always_ff @(posedge clk) begin
fn3_ex <= branch_inputs.fn3;
if (branch_ex.new_request_dec)
fn3_ex <= branch_inputs.fn3;
end
always_ff @(posedge clk) begin
equal_ex <= equal;
lessthan_ex <= lessthan;
bt.ex_pc <= branch_inputs.dec_pc;
@ -114,7 +116,7 @@ module branch_unit(
bt.njump_pc <= pc_plus_4;
end
//if the destination reg is zero, the result is not "written back" to the register file.
assign new_jal_jalr_dec = (branch_inputs.jal | branch_inputs.jalr) & ~branch_inputs.rdx0;
always_ff @(posedge clk) begin
@ -163,8 +165,8 @@ module branch_unit(
end
end
assign branch_wb.done = (done & ~branch_wb.accepted);
assign branch_wb.early_done = branch_ex.possible_issue & new_jal_jalr_dec;
assign branch_wb.done_next_cycle = (done & ~branch_wb.accepted);
assign branch_wb.done_on_first_cycle = 1;//branch_ex.possible_issue & new_jal_jalr_dec;
/*********************************************/

View file

@ -654,8 +654,8 @@ module csr_unit (
end
end
assign csr_wb.early_done = 0;
assign csr_wb.done = csr_ex.new_request | (done & ~csr_wb.accepted);
assign csr_wb.done_on_first_cycle = 0;
assign csr_wb.done_next_cycle = csr_ex.new_request | (done & ~csr_wb.accepted);
always_ff @(posedge clk) begin
if (rst) begin

View file

@ -31,7 +31,7 @@ module dbram(
ls_sub_unit_interface.sub_unit ls,
output logic[31:0] data_out,
bram_interface.user data_bram
local_memory_interface.master data_bram
);
assign ls.ready = 1;

View file

@ -136,36 +136,25 @@ module decode(
assign rf_decode.instruction_issued = advance & uses_rd;
assign rf_decode.id = id_gen.issue_id;
//Issue logic
always_comb begin
case (opcode)
LUI : illegal_instruction = 1'b0;
AUIPC : illegal_instruction = 1'b0;
JAL : illegal_instruction = 1'b0;
JALR : illegal_instruction = 1'b0;
BRANCH : illegal_instruction = 1'b0;
LOAD : illegal_instruction = 1'b0;
STORE : illegal_instruction = 1'b0;
ARITH_IMM : illegal_instruction = 1'b0;
ARITH : begin
if (!USE_MUL && !USE_DIV)
illegal_instruction = ib.data_out.instruction[25];
else if (!USE_MUL && USE_DIV)
illegal_instruction = ib.data_out.instruction[25] & ~fn3[2];
else if (!USE_MUL && !USE_DIV)
illegal_instruction = ib.data_out.instruction[25] & fn3[2];
else
illegal_instruction = 1'b0;
end
FENCE : illegal_instruction = 1'b0;
AMO : illegal_instruction = 1'b0;
SYSTEM : illegal_instruction = 1'b0;
default : illegal_instruction = 1'b1;
endcase
illegal_instruction = !(opcode inside {LUI, AUIPC, JAL, JALR, BRANCH, LOAD, STORE, ARITH, ARITH_IMM, FENCE, AMO, SYSTEM});
if (opcode == ARITH) begin
if (!USE_MUL && !USE_DIV)
illegal_instruction = ib.data_out.instruction[25];
else if (!USE_MUL && USE_DIV)
illegal_instruction = ib.data_out.instruction[25] & ~fn3[2];
else if (!USE_MUL && !USE_DIV)
illegal_instruction = ib.data_out.instruction[25] & fn3[2];
else
illegal_instruction = 0;
end
end
one_hot_to_integer #(NUM_WB_UNITS) iq_id (.one_hot(new_request), .int_out(iq.data_in.unit_id));
assign iq.future_rd_addr = future_rd_addr;
assign iq.uses_rd = uses_rd && (future_rd_addr != 0);
assign iq.data_in.id = id_gen.issue_id;
assign iq.new_issue = advance & uses_rd;
@ -188,53 +177,39 @@ module decode(
assign mult_div_op = (opcode_trim == ARITH_T) && ib.data_out.instruction[25];
assign new_request[BRANCH_UNIT_ID] = ((opcode_trim == BRANCH_T) || (opcode_trim == JAL_T) || (opcode_trim == JALR_T));
assign new_request[ALU_UNIT_ID] = ((opcode_trim == ARITH_T) && ~ib.data_out.instruction[25]) || (opcode_trim == ARITH_IMM_T) || (opcode_trim == AUIPC_T) || (opcode_trim == LUI_T);
assign new_request[LS_UNIT_ID] = (opcode_trim == LOAD_T || opcode_trim == STORE_T || opcode_trim == AMO_T);
assign new_request[BRANCH_UNIT_ID] = opcode_trim inside {BRANCH_T, JAL_T, JALR_T};
assign new_request[ALU_UNIT_ID] = ((opcode_trim == ARITH_T) && ~ib.data_out.instruction[25]) || opcode_trim inside {ARITH_IMM_T, AUIPC_T, LUI_T};
assign new_request[LS_UNIT_ID] = opcode_trim inside {LOAD_T, STORE_T, 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];
else
assign new_request[MUL_UNIT_ID] = 0;
endgenerate
generate if (USE_DIV)
assign new_request[DIV_UNIT_ID] = mult_div_op & fn3[2];
else
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];
// assign new_request[CUSTOM_ID_1] = (opcode_trim == CUSTOM_T) && ~ib.data_out.instruction[25] && ib.data_out.instruction[26];
// assign new_request[CUSTOM_ID_2] = (opcode_trim == CUSTOM_T) && ib.data_out.instruction[25] && ~ib.data_out.instruction[26];
// assign new_request[CUSTOM_ID_3] = (opcode_trim == CUSTOM_T) && ib.data_out.instruction[25] && ib.data_out.instruction[26];
//
assign issue_ready[BRANCH_UNIT_ID] = new_request[BRANCH_UNIT_ID] & (branch_ex.ready | ~uses_rd);//| ~uses_rd
assign issue_ready[ALU_UNIT_ID] = new_request[ALU_UNIT_ID] & alu_ex.ready;
assign issue_ready[LS_UNIT_ID] = new_request[LS_UNIT_ID] & ls_ex.ready;
assign issue_ready[CSR_UNIT_ID] = new_request[CSR_UNIT_ID] & csr_ex.ready;
assign issue_ready[MUL_UNIT_ID] = new_request[MUL_UNIT_ID] & mul_ex.ready;
assign issue_ready[DIV_UNIT_ID] = new_request[DIV_UNIT_ID] & div_ex.ready;
// assign issue_ready[CUSTOM_ID_0] = new_request[CUSTOM_ID_0] & cust0_ex.ready;
//assign issue_ready[CUSTOM_ID_1] = new_request[CUSTOM_ID_1] & cust1_ex.ready;
// assign issue_ready[CUSTOM_ID_2] = new_request[CUSTOM_ID_2] & cust2_ex.ready;
// assign issue_ready[CUSTOM_ID_3] = new_request[CUSTOM_ID_3] & cust3_ex.ready;
generate if (USE_MUL)
assign issue_ready[MUL_UNIT_ID] = new_request[MUL_UNIT_ID] & mul_ex.ready;
endgenerate
generate if (USE_DIV)
assign issue_ready[DIV_UNIT_ID] = new_request[DIV_UNIT_ID] & div_ex.ready;
endgenerate
assign issue[BRANCH_UNIT_ID] = issue_valid & operands_ready & issue_ready[BRANCH_UNIT_ID];
assign issue[ALU_UNIT_ID] = issue_valid & operands_ready & issue_ready[ALU_UNIT_ID];
assign issue[LS_UNIT_ID] = issue_valid & load_store_operands_ready & issue_ready[LS_UNIT_ID];
assign issue[CSR_UNIT_ID] = issue_valid & operands_ready & issue_ready[CSR_UNIT_ID];
assign issue[MUL_UNIT_ID] = issue_valid & operands_ready & issue_ready[MUL_UNIT_ID];
assign issue[DIV_UNIT_ID] = issue_valid & operands_ready & issue_ready[DIV_UNIT_ID];
//assign issue[CUSTOM_ID_0] = issue_valid & operands_ready & issue_ready[CUSTOM_ID_0];
//assign issue[CUSTOM_ID_1] = issue_valid & operands_ready & issue_ready[CUSTOM_ID_1];
//assign issue[CUSTOM_ID_2] = issue_valid & operands_ready & issue_ready[CUSTOM_ID_2];
//assign issue[CUSTOM_ID_3] = issue_valid & operands_ready & issue_ready[CUSTOM_ID_3];
generate if (USE_MUL)
assign issue[MUL_UNIT_ID] = issue_valid & operands_ready & issue_ready[MUL_UNIT_ID];
endgenerate
generate if (USE_DIV)
assign issue[DIV_UNIT_ID] = issue_valid & operands_ready & issue_ready[DIV_UNIT_ID];
endgenerate
assign advance = (|issue_ready) & issue_valid & load_store_operands_ready;
@ -273,17 +248,8 @@ module decode(
XOR_fn3 : alu_op = ALU_LOGIC;
OR_fn3 : alu_op = ALU_LOGIC;
AND_fn3 : alu_op = ALU_LOGIC;
SRA_fn3 : alu_op = ALU_SHIFTR;
ADD_SUB_fn3 : alu_op = ALU_LOGIC;
endcase
end
always_comb begin
case (fn3)
XOR_fn3 : alu_logic_op = ALU_XOR;
OR_fn3 : alu_logic_op = ALU_OR;
AND_fn3 : alu_logic_op = ALU_AND;
default: alu_logic_op = ALU_ADD_SUB;
SRA_fn3 : alu_op = ALU_SHIFT;
ADD_SUB_fn3 : alu_op = ALU_ADD_SUB;
endcase
end
@ -302,15 +268,14 @@ module decode(
always_ff @(posedge clk) begin
if (issue[ALU_UNIT_ID]) begin
alu_inputs.in1 <= alu_rs1_data;
alu_inputs.in2 <= alu_rs2_data;
alu_inputs.in1 <= {(alu_rs1_data[XLEN-1] & ~fn3[0]), alu_rs1_data};//(fn3[0] is SLTU_fn3);
alu_inputs.in2 <= {(alu_rs2_data[XLEN-1] & ~fn3[0]), alu_rs2_data};
alu_inputs.subtract <= alu_sub;
alu_inputs.arith <= alu_rs1_data[XLEN-1] & ib.data_out.instruction[30];//shift in bit
alu_inputs.shifter_in <= fn3[2] ? rf_decode.rs1_data : left_shift_in;
alu_inputs.sltu <= fn3[0];//(fn3 ==SLTU_fn3);
alu_inputs.logic_op <= opcode[2] ? ALU_ADD_SUB : alu_logic_op;//put LUI and AUIPC through adder path
alu_inputs.op <= opcode[2] ? ALU_LOGIC : alu_op;//put LUI and AUIPC through adder path
end
alu_inputs.lshift <= ~fn3[2];
alu_inputs.fn3 <= fn3;
alu_inputs.op <= opcode[2] ? ALU_ADD_SUB : alu_op;//put LUI and AUIPC through adder path
end
end
//----------------------------------------------------------------------------------
@ -326,7 +291,7 @@ module decode(
assign ls_inputs.fn3 = ls_inputs.is_amo ? LS_W_fn3 : fn3;
assign ls_inputs.amo = USE_AMO ? ib.data_out.instruction[31:27] : 0;
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.load = (opcode_trim inside {LOAD_T, 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.id = id_gen.issue_id;
@ -357,7 +322,7 @@ module decode(
assign branch_inputs.rs2 = rf_decode.rs2_data;
assign branch_inputs.fn3 = fn3;
assign branch_inputs.dec_pc = ib.data_out.pc;
assign branch_inputs.use_signed = !((fn3 == BLTU_fn3) || (fn3 == BGEU_fn3));
assign branch_inputs.use_signed = !(fn3 inside {BLTU_fn3, BGEU_fn3});
assign branch_inputs.rdx0 = ~uses_rd;//(future_rd_addr == 0); jal jalr x0
assign branch_inputs.rs1_addr = rs1_addr;
assign branch_inputs.rd_addr = future_rd_addr;
@ -390,38 +355,40 @@ module decode(
//----------------------------------------------------------------------------------
//Mul Div unit inputs
//----------------------------------------------------------------------------------
assign mul_ex.new_request_dec = issue[MUL_UNIT_ID];
assign mul_inputs.rs1 = rf_decode.rs1_data;
assign mul_inputs.rs2 = rf_decode.rs2_data;
assign mul_inputs.op = fn3[1:0];
generate if (USE_MUL)
assign mul_ex.new_request_dec = issue[MUL_UNIT_ID];
assign mul_inputs.rs1 = rf_decode.rs1_data;
assign mul_inputs.rs2 = rf_decode.rs2_data;
assign mul_inputs.op = fn3[1:0];
endgenerate
//If a subsequent div request uses the same inputs then
//don't rerun div operation
always_ff @(posedge clk) begin
if (issue[DIV_UNIT_ID]) begin
prev_div_rs1_addr <= rs1_addr;
prev_div_rs2_addr <= rs2_addr;
generate if (USE_DIV)
always_ff @(posedge clk) begin
if (issue[DIV_UNIT_ID]) begin
prev_div_rs1_addr <= rs1_addr;
prev_div_rs2_addr <= rs2_addr;
end
end
always_ff @(posedge clk) begin
if (rst)
prev_div_result_valid <= 0;
else if (advance) begin
if(new_request[DIV_UNIT_ID] && !(future_rd_addr inside {rs1_addr, rs2_addr}))
prev_div_result_valid <=1;
else if (uses_rd && (future_rd_addr inside {prev_div_rs1_addr, prev_div_rs2_addr}))
prev_div_result_valid <=0;
end
end
end
always_ff @(posedge clk) begin
if (rst)
prev_div_result_valid <= 0;
else if (advance) begin
if(new_request[DIV_UNIT_ID] && !(rs1_addr == future_rd_addr || rs2_addr == future_rd_addr))
prev_div_result_valid <=1;
else if (uses_rd && (prev_div_rs1_addr == future_rd_addr || prev_div_rs2_addr == future_rd_addr))
prev_div_result_valid <=0;
end
end
assign div_ex.new_request_dec = issue[DIV_UNIT_ID];
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 = 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);
assign div_ex.new_request_dec = issue[DIV_UNIT_ID];
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.div_zero = (rf_decode.rs2_data == 0);
endgenerate
//----------------------------------------------------------------------------------
always_ff @(posedge clk) begin
if(rst) begin

View file

@ -37,27 +37,23 @@ module div_unit(
logic [31:0] quotient;
logic [31:0] remainder;
logic [31:0] result;
logic signed_divop;
logic quotient_signed;
logic remainder_signed;
logic dividend_signed;
logic divisor_signed;
logic div_abort;
logic start;
logic in_progress;
logic output_ready;
logic ack;
logic [31:0] complementerA;
logic [31:0] complementerB;
logic negateA;
logic negateB;
logic [31:0] inA;
logic [31:0] inB;
logic [31:0] div_result_muxed;
logic [31:0] result_input;
logic negateResult;
logic [31:0] div_result_sign_corrected;
logic [31:0] wb_div_result;
@ -79,20 +75,21 @@ module div_unit(
assign stage1 = input_fifo.data_out;
/*********************************************/
assign start = input_fifo.valid & ( ~in_progress);
assign output_ready = ~div_wb.done_next_cycle | (div_wb.done_next_cycle & div_wb.accepted);
assign ack = div_complete & output_ready;
assign start = input_fifo.valid & (~in_progress) & ~(stage1.reuse_result | stage1.div_zero);
//Abort prevents divider circuit from starting in the case that we are done in one cycle
assign div_abort = input_fifo.valid & (stage1.div_zero | stage1.reuse_result);
assign div_done = (div_complete | div_abort) & ~wb_fifo.full;
assign div_done = (div_complete | (input_fifo.valid & (stage1.reuse_result | stage1.div_zero))) & output_ready;
//If more than one cycle, set in_progress so that multiple start signals are not sent to the div unit. Also in progress if an abort occurs but the output FIFO is full
always_ff @(posedge clk) begin
if (rst) begin
if (rst)
in_progress <= 0;
end else if (start & ((div_abort & wb_fifo.full) | (~div_abort))) begin
else if (start)
in_progress <= 1;
end else if (div_done) begin
else if (ack)
in_progress <= 0;
end
end
//Input and output sign determination
@ -103,52 +100,42 @@ module div_unit(
assign quotient_signed = signed_divop & (stage1.rs1[31] ^ stage1.rs2[31]);
assign remainder_signed = signed_divop & (stage1.rs1[31]);
// Shared adders for sign conversion of inputs and outputs as they never occur on the same cycle
//(div_complete | stage1.reuse_result) instead of div_done as other signals are not relevant for sign conversion
//************
assign inA = (div_complete | stage1.reuse_result) ? quotient : stage1.rs1;
assign inB = (div_complete | stage1.reuse_result) ? remainder : stage1.rs2;
assign negateA = (div_complete | stage1.reuse_result) ? quotient_signed : dividend_signed;
assign negateB = (div_complete | stage1.reuse_result) ? remainder_signed : divisor_signed;
assign complementerA = (dividend_signed ? ~stage1.rs1 : stage1.rs1) + dividend_signed;
assign complementerB = (divisor_signed ? ~stage1.rs2 : stage1.rs2) + divisor_signed;
assign complementerA = (negateA ? ~inA : inA) + negateA;
assign complementerB = (negateB ? ~inB : inB) + negateB;
assign result_input = stage1.op[1] ? remainder : quotient;
assign negateResult = (stage1.op[1] ? remainder_signed : quotient_signed);
assign div_result_sign_corrected = (negateResult ? ~result_input : result_input) + negateResult;
assign wb_div_result = stage1.div_zero ? (stage1.op[1] ? stage1.rs1 : '1) : div_result_sign_corrected;
//*************
//Synthesis time algorithm choice for divider
generate
if(USE_VARIABLE_LATENCY_DIV)
quickdiv #(XLEN) div (.*, .start(start & ~div_abort), .A(complementerA), .B(complementerB), .Q(quotient), .R(remainder), .complete(div_complete), .ack(div_done));
quickdiv #(XLEN) div (.*, .start(start), .A(complementerA), .B(complementerB), .Q(quotient), .R(remainder), .complete(div_complete), .ack(ack));
else
normdiv #(XLEN) div (.*, .start(start & ~div_abort), .A(complementerA), .B(complementerB), .Q(quotient), .R(remainder), .complete(div_complete), .ack(div_done));
normdiv #(XLEN) div (.*, .start(start), .A(complementerA), .B(complementerB), .Q(quotient), .R(remainder), .complete(div_complete), .ack(ack));
endgenerate
//Output muxing
always_comb begin
case (stage1.op)
DIV_fn3[1:0] : div_result_muxed <= stage1.div_zero ? '1 : complementerA;
DIVU_fn3[1:0] : div_result_muxed <= stage1.div_zero ? '1 : complementerA;
REM_fn3[1:0] : div_result_muxed <=stage1.div_zero ? stage1.rs1 : complementerB;
REMU_fn3[1:0] : div_result_muxed <= stage1.div_zero ? stage1.rs1 : complementerB;
endcase
/*********************************
* Output registering/handshaking
*********************************/
always_ff @(posedge clk) begin
if (div_done)
div_wb.rd <= wb_div_result;
end
/*********************************
* Output FIFO
*********************************/
taiga_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(DIV_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) output_fifo (.fifo(wb_fifo), .*);
always_ff @(posedge clk) begin
if (rst)
div_wb.done_next_cycle <= 0;
else if (div_done)
div_wb.done_next_cycle <= 1;
else if (div_wb.accepted)
div_wb.done_next_cycle <= 0;
end
assign wb_fifo.data_in = div_result_muxed;
assign wb_fifo.push = div_done;
assign wb_fifo.pop = div_wb.accepted;
assign div_wb.rd = wb_fifo.data_out;
assign div_wb.done = wb_fifo.early_valid;
assign div_wb.early_done = 0;//div_done | (div_wb.done & ~div_wb.accepted);
/*********************************************/
assign div_wb.done_on_first_cycle = 0;
endmodule

View file

@ -34,7 +34,7 @@ module fetch(
ras_interface.fetch ras,
tlb_interface.mem tlb,
bram_interface.user instruction_bram,
local_memory_interface.master instruction_bram,
input logic icache_on,
l1_arbiter_request_interface.requester l1_request,
l1_arbiter_return_interface.requester l1_response,
@ -46,22 +46,24 @@ module fetch(
);
localparam NUM_SUB_UNITS = USE_I_SCRATCH_MEM + USE_ICACHE;
localparam NUM_SUB_UNITS_W = $clog2(NUM_SUB_UNITS);
localparam BRAM_ID = 0;
localparam ICACHE_ID = 1;
localparam ICACHE_ID = USE_I_SCRATCH_MEM;
fetch_sub_unit_interface fetch_sub[1:0]();
fetch_sub_unit_interface fetch_sub[NUM_SUB_UNITS-1:0]();
logic cache_access;
logic bram_access;
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];
logic units_ready;
logic mem_ready;
logic [31:0] offset;
logic [31:0] next_pc_source;
logic [31:0] next_pc;
logic [31:0] if_pc;
logic stage1_prediction;
logic space_in_inst_buffer;
logic new_mem_request;
@ -74,10 +76,8 @@ module fetch(
logic [31:0] stage2_phys_address;
logic stage2_valid;
logic stage2_prediction;
logic stage2_cache_access;
logic pc_valid;
logic update_pc;
logic[6:0] opcode;
logic[4:0] opcode_trimmed;
@ -88,49 +88,51 @@ module fetch(
logic sys_op;
logic jal_jalr_x0;
assign flush = bt.flush | exception;
logic rs1_link, rd_link, rs1_eq_rd, use_ras;
logic predicted_control_flow;
always_ff @(posedge clk) begin
if (rst) begin
pc_valid <= 0;
end else begin
pc_valid <= 1;
logic[$clog2(FETCH_BUFFER_DEPTH+1)-1:0] inflight_count;
/////////////////////////////////////////
genvar i;
generate
for(i=0; i < NUM_SUB_UNITS; i++) begin
assign unit_ready[i] = fetch_sub[i].ready;
assign unit_data_valid[i] = fetch_sub[i].data_valid;
end
end
endgenerate
assign units_ready = &unit_ready;
assign bt.next_pc_valid = pc_valid;
assign fetch_flush = (bt.flush | exception);
assign flush = fetch_flush;
assign update_pc = new_mem_request | fetch_flush;
//Fetch PC
always_ff @(posedge clk) begin
if (rst) begin
if (rst)
if_pc <= RESET_VEC;
end
else if (new_mem_request | flush) begin
else if (update_pc)
if_pc <= {next_pc[31:2], 2'b0};
end
end
always_comb begin
if (exception)
next_pc = RESET_VEC;
else if (bt.flush)
next_pc = bt.branch_taken ? bt.jump_pc : bt.njump_pc;
else if (bt.use_prediction) begin
if (bt.use_ras & ras.valid)
next_pc = ras.addr;
else
next_pc = bt.predicted_pc;
end
//else if (predicted_control_flow)
// next_pc = (use_ras & ras.valid) ? ras.addr : bt.predicted_pc;
else if (bt.use_prediction)
next_pc = (bt.use_ras & ras.valid) ? ras.addr : bt.predicted_pc;
else
next_pc = if_pc + 4;
end
assign bt.new_mem_request = new_mem_request | bt.flush;
assign bt.new_mem_request = update_pc;
assign bt.next_pc = next_pc;
assign if2_pc = if_pc;
assign bt.if_pc = if_pc;
/*************************************
* TLB
@ -139,81 +141,83 @@ module fetch(
assign tlb.execute = 1;
assign tlb.rnw = 0;
always_ff @(posedge clk) begin
if(rst)
stage2_valid <= 0;
if (new_mem_request)
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_cache_access <= cache_access;
end
end
//////////////////////////////////////////////
//Cache check done before cache access
assign cache_access = tlb.physical_address[31:32-MEMORY_BIT_CHECK] == MEMORY_ADDR_L[31:32-MEMORY_BIT_CHECK];
//BRAM check can be done a cycle later, can be used for address checking
assign bram_access = stage2_phys_address[31:32-SCRATCH_BIT_CHECK] == SCRATCH_ADDR_L[31:32-SCRATCH_BIT_CHECK];
assign mem_ready = fetch_sub[ICACHE_ID].ready;
assign fetch_flush = (bt.flush | exception);
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;
assign fetch_sub[BRAM_ID].stage1_addr = tlb.physical_address;
assign fetch_sub[ICACHE_ID].stage1_addr = tlb.physical_address;
assign fetch_sub[BRAM_ID].stage2_addr = stage2_phys_address;
assign fetch_sub[ICACHE_ID].stage2_addr = stage2_phys_address;
//Memory interfaces
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].data_valid = 0;
assign fetch_sub[BRAM_ID].data_out = 0;
end
endgenerate
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].data_valid = 0;
assign fetch_sub[ICACHE_ID].data_out = 0;
end
endgenerate
//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
always_ff @(posedge clk) begin
if (rst)
delayed_flush <= 0;
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;
if (rst | fetch_flush)
inflight_count <= 0;
else if (new_mem_request & ~ib.pop)
inflight_count <= inflight_count + 1;
else if (~new_mem_request & ib.pop)
inflight_count <= inflight_count - 1;
end
assign mem_valid = ~(bt.flush | exception | delayed_flush);
assign new_issue = mem_valid & (fetch_sub[BRAM_ID].data_valid | fetch_sub[ICACHE_ID].data_valid);
assign ib.push = new_issue;
assign ib.flush = bt.flush;
assign space_in_inst_buffer = inflight_count < FETCH_BUFFER_DEPTH;
assign new_mem_request = tlb.complete & (~fetch_flush) & space_in_inst_buffer & units_ready;
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);
//Memory interfaces
generate if (USE_I_SCRATCH_MEM) begin
ibram i_bram (.*, .fetch_sub(fetch_sub[BRAM_ID]));
assign sub_unit_address_match[BRAM_ID] = (tlb.physical_address[31:32-SCRATCH_BIT_CHECK] == SCRATCH_ADDR_L[31:32-SCRATCH_BIT_CHECK]);
assign fetch_sub[BRAM_ID].new_request = new_mem_request & sub_unit_address_match[BRAM_ID];
assign fetch_sub[BRAM_ID].stage1_addr = tlb.physical_address;
assign fetch_sub[BRAM_ID].stage2_addr = stage2_phys_address;
assign unit_data_array[BRAM_ID] = fetch_sub[BRAM_ID].data_out;
end
endgenerate
generate if (USE_ICACHE) begin
icache i_cache (.*, .fetch_sub(fetch_sub[ICACHE_ID]));
assign sub_unit_address_match[ICACHE_ID] = tlb.physical_address[31:32-MEMORY_BIT_CHECK] == MEMORY_ADDR_L[31:32-MEMORY_BIT_CHECK];
assign fetch_sub[ICACHE_ID].new_request = new_mem_request & sub_unit_address_match[ICACHE_ID];
assign fetch_sub[ICACHE_ID].stage1_addr = tlb.physical_address;
assign fetch_sub[ICACHE_ID].stage2_addr = stage2_phys_address;
assign unit_data_array[ICACHE_ID] = fetch_sub[ICACHE_ID].data_out;
always_ff @(posedge clk) begin
if(rst)
stage2_valid <= 0;
else if (new_mem_request)
stage2_valid <= 1;
else if (new_issue | fetch_flush)
stage2_valid <= 0;
end
always_ff @(posedge clk) begin
if (new_mem_request) begin
last_sub_unit_id <= sub_unit_address_match;
end
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
always_ff @(posedge clk) begin
if (rst)
delayed_flush <= 0;
else if (fetch_flush & stage2_valid & last_sub_unit_id[ICACHE_ID] & ~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;
end
end else begin
assign delayed_flush = 0;
end
endgenerate
assign mem_valid = ~(bt.flush | exception | delayed_flush);
assign new_issue = mem_valid & (|unit_data_valid);
assign ib.push = new_issue;
assign ib.flush = fetch_flush;
always_comb begin
ib.data_in.instruction = {32{unit_data_valid[0]}} & unit_data_array[0];
for(int i=1; i < NUM_SUB_UNITS; i++) begin
ib.data_in.instruction |= {32{unit_data_valid[i]}} & unit_data_array[i];
end
end
assign ib.data_in.pc = stage2_phys_address;
@ -225,12 +229,20 @@ module fetch(
assign csr_imm_op = (opcode_trimmed == SYSTEM_T) && fn3[2];
assign sys_op = (opcode_trimmed == SYSTEM_T) && (fn3 == 0);
assign jal_jalr_x0 = ((opcode_trimmed == JAL_T) || (opcode_trimmed == JALR_T)) && (ib.data_in.instruction[11:7] == 0);//rd is x0
assign jal_jalr_x0 = (opcode_trimmed inside {JAL_T, JALR_T}) && (ib.data_in.instruction[11:7] == 0);//rd is 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);
assign predicted_control_flow = opcode_trimmed inside {JAL_T, JALR_T, BRANCH_T};
assign rs1_link = (ib.data_in.instruction[19:15] ==? 5'b00?01);
assign rd_link = (ib.data_in.instruction[11:7] ==? 5'b00?01);
assign rs1_eq_rd = (ib.data_in.instruction[19:15] == ib.data_in.instruction[11:7]);
assign use_ras = ((opcode_trimmed == JALR_T & ((rs1_link & ~rd_link) | (rs1_link & rd_link & ~rs1_eq_rd))));
assign ib.data_in.uses_rs1 = !(opcode_trimmed inside {LUI_T, AUIPC_T, JAL_T, FENCE_T} || csr_imm_op || sys_op);
assign ib.data_in.uses_rs2 = opcode_trimmed inside {BRANCH_T, STORE_T, ARITH_T, AMO_T, CUSTOM_T};
assign ib.data_in.uses_rd = !(opcode_trimmed inside {BRANCH_T, STORE_T, FENCE_T} || sys_op || jal_jalr_x0);
endmodule

View file

@ -28,23 +28,11 @@ module ibram(
input logic rst,
fetch_sub_unit_interface.sub_unit fetch_sub,
bram_interface.user instruction_bram
local_memory_interface.master instruction_bram
);
logic stage2_adv;
logic address_range_valid;
assign fetch_sub.ready = 1;
always_ff @ (posedge clk) begin
if (rst) begin
stage2_adv <= 0;
end
else begin
stage2_adv <= fetch_sub.new_request;
end
end
assign instruction_bram.addr = fetch_sub.stage1_addr[31:2];
assign instruction_bram.en = fetch_sub.new_request;
assign instruction_bram.be = '0;
@ -60,5 +48,4 @@ module ibram(
fetch_sub.data_valid <= 0;
end
endmodule

View file

@ -58,15 +58,6 @@ module icache(
* General Control Logic
*************************************/
always_ff @ (posedge clk) begin
if (rst) begin
hit_allowed <= 0;
end
else begin
hit_allowed <= fetch_sub.new_request & icache_on;
end
end
always_ff @ (posedge clk) begin
if (rst)
second_cycle <= 0;
@ -130,14 +121,14 @@ module icache(
.stage2_addr(fetch_sub.stage2_addr),
.update_way(tag_update_way),
.update(tag_update),
.stage1_adv(fetch_sub.new_request)
.stage1_adv(fetch_sub.new_request & icache_on)
);
//Data Banks
genvar i;
generate
for (i=0; i < ICACHE_WAYS; i++) begin : data_bank_gen
byte_en_BRAM #(ICACHE_LINES*ICACHE_LINE_W) data_bank (
for (i=0; i < ICACHE_WAYS; i++) begin : idata_bank_gen
byte_en_BRAM #(ICACHE_LINES*ICACHE_LINE_W) idata_bank (
.clk(clk),
.addr_a(fetch_sub.stage1_addr[ICACHE_LINE_ADDR_W+ICACHE_SUB_LINE_ADDR_W+2-1:2]),
.addr_b({fetch_sub.stage2_addr[ICACHE_LINE_ADDR_W+ICACHE_SUB_LINE_ADDR_W+2-1:ICACHE_SUB_LINE_ADDR_W+2], word_count}),
@ -180,7 +171,7 @@ module icache(
end
end
assign fetch_sub.data_valid = miss_data_ready | (hit_allowed & tag_hit);
assign fetch_sub.data_valid = miss_data_ready | tag_hit;
/*************************************
* Pipeline Advancement
@ -194,14 +185,14 @@ module icache(
memory_complete <= line_complete;
end
assign fetch_sub.ready = (hit_allowed & tag_hit) | memory_complete | idle;//~(second_cycle & ~tag_hit) & ~miss;
assign fetch_sub.ready = tag_hit | memory_complete | idle;//~(second_cycle & ~tag_hit) & ~miss;
always_ff @ (posedge clk) begin
if (rst)
idle <= 1;
else if (fetch_sub.new_request)
idle <= 0;
else if (memory_complete | (hit_allowed & tag_hit)) //read miss OR write through complete
else if (memory_complete | tag_hit) //read miss OR write through complete
idle <= 1;
end

View file

@ -81,13 +81,16 @@ module inflight_queue
//future rd_addt table
logic [4:0] rd_addrs [INFLIGHT_QUEUE_DEPTH-1:0];
logic rd_addr_not_zero [INFLIGHT_QUEUE_DEPTH-1:0];
always_ff @ (posedge clk) begin
if (iq.new_issue) begin
rd_addrs[iq.data_in.id] <= iq.future_rd_addr;
rd_addr_not_zero[iq.data_in.id] <= iq.uses_rd;
end
end
assign iq.wb_rd_addr = rd_addrs[iq.wb_id];
assign iq.wb_uses_rd = rd_addr_not_zero[iq.wb_id];
endmodule

View file

@ -44,7 +44,13 @@ module instruction_buffer
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;
always_ff @ (posedge clk) begin
ib.data_out <= ib_fifo.data_out;
end
//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;

View file

@ -24,17 +24,6 @@ import taiga_config::*;
import taiga_types::*;
import l2_config_and_types::*;
interface bram_interface;
logic[29:0] addr;
logic en;
logic[XLEN/8-1:0] be;
logic[XLEN-1:0] data_in;
logic[XLEN-1:0] data_out;
modport bram (input addr, en, be, data_in, output data_out);
modport user (output addr, en, be, data_in, input data_out);
endinterface
interface branch_table_interface;
logic[31:0] if_pc;
logic[31:0] dec_pc;
@ -44,8 +33,6 @@ interface branch_table_interface;
logic[31:0] next_pc;
logic next_pc_valid;
logic branch_taken;
logic branch_ex;
logic prediction_dec;
@ -58,8 +45,8 @@ interface branch_table_interface;
logic use_prediction;
logic use_ras;
logic flush;
modport branch_table (input if_pc, dec_pc, ex_pc, next_pc, njump_pc, jump_pc, branch_taken, branch_ex, is_return_ex, prediction_dec, next_pc_valid, new_mem_request, output predicted_pc, prediction, use_prediction, use_ras, flush);
modport fetch (input predicted_pc, prediction, use_prediction, branch_taken, flush, njump_pc, jump_pc, use_ras, output if_pc, next_pc, next_pc_valid, new_mem_request);
modport branch_table (input if_pc, dec_pc, ex_pc, next_pc, njump_pc, jump_pc, branch_taken, branch_ex, is_return_ex, prediction_dec, new_mem_request, output predicted_pc, prediction, use_prediction, use_ras, flush);
modport fetch (input predicted_pc, prediction, use_prediction, branch_taken, flush, njump_pc, jump_pc, use_ras, output if_pc, next_pc, new_mem_request);
modport decode (output dec_pc);
modport branch_unit (output branch_taken, prediction_dec, branch_ex, is_return_ex, ex_pc, njump_pc, jump_pc);
@ -88,12 +75,12 @@ interface ras_interface;
endinterface
interface unit_writeback_interface;
logic done;
logic early_done;
logic done_next_cycle;
logic done_on_first_cycle;
logic accepted;
logic [XLEN-1:0] rd;
modport writeback (input done, early_done, rd, output accepted);
modport unit (output done, early_done, rd, input accepted);
modport writeback (input done_next_cycle, done_on_first_cycle, rd, output accepted);
modport unit (output done_next_cycle, done_on_first_cycle, rd, input accepted);
endinterface
//********************************
@ -160,14 +147,17 @@ interface inflight_queue_interface;
inflight_queue_packet data_in;
logic [4:0] future_rd_addr;
logic uses_rd;
logic wb_uses_rd;
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, 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);
modport queue (input pop, data_in, new_issue, future_rd_addr, uses_rd, wb_id, output data_out, wb_rd_addr, wb_uses_rd, shift_pop, valid);
modport decode (output data_in, future_rd_addr, uses_rd, new_issue);
modport wb (input data_in, future_rd_addr, uses_rd, wb_uses_rd, shift_pop, valid, data_out, wb_rd_addr, output pop, wb_id);
endinterface
@ -197,7 +187,7 @@ interface instruction_buffer_interface;
logic early_full;
modport buffer (input push, pop, flush, data_in, output data_out, valid, full, early_full);
modport fetch (input full, early_full, output push, data_in, flush);
modport fetch (input full, early_full, pop, output push, data_in, flush);
modport decode (input valid, data_out, output pop);
//modport exception_control (output flush);
endinterface

View file

@ -77,7 +77,7 @@ module itag_banks(
.data_in_b(stage2_tag), .data_out_b()
);
assign tag_hit_way[i] = hit_allowed & (stage2_tag == tag_line[i]);
assign tag_hit_way[i] = ({hit_allowed,stage2_tag} == {1'b1,tag_line[i]});
end
endgenerate

View file

@ -41,7 +41,7 @@ module load_store_unit (
axi_interface.master m_axi,
avalon_interface.master m_avalon,
bram_interface.user data_bram,
local_memory_interface.master data_bram,
output logic inorder,
unit_writeback_interface.unit ls_wb
@ -71,13 +71,15 @@ module load_store_unit (
logic [3:0] be;
logic [31:0] unit_muxed_load_data;
logic [31:0] aligned_load_data;
logic [7:0] byte_load_data;
logic [15:0] halfword_load_data;
logic [31:0] final_load_data;
logic [31:0] rs2_muxed;
logic [31:0] most_recent_load;
logic [31:0] forwarded_data;
logic [31:0] previous_load;
logic [31:0] previous_load, previous_load_r;
logic [31:0] stage1_raw_data;
logic [31:0] unit_data_array [NUM_SUB_UNITS-1:0];
@ -92,7 +94,7 @@ module load_store_unit (
logic dcache_forward_data;
logic [2:0] dcache_stage2_fn3;
logic [$clog2(LS_OUTPUT_BUFFER_DEPTH)-1:0] inflight_count;
logic [1:0] inflight_count;
//AMO support
@ -125,9 +127,9 @@ module load_store_unit (
always_ff @(posedge clk) begin
if (rst)
inflight_count <= 0;
else if (issue_request & stage1.load & ~ls_wb.accepted)
else if (load_attributes.push & ~ls_wb.accepted)
inflight_count <= inflight_count + 1;
else if (~issue_request & stage1.load & ls_wb.accepted)
else if (~load_attributes.push & ls_wb.accepted)
inflight_count <= inflight_count - 1;
end
@ -146,14 +148,14 @@ module load_store_unit (
assign current_unit = sub_unit_address_match;
always_ff @ (posedge clk) begin
if (issue_request)
if (load_attributes.push)
last_unit <= sub_unit_address_match;
end
//When switching units, ensure no outstanding loads so that there can be no timing collisions with results
assign unit_stall = (current_unit != last_unit) & ~load_attributes.empty;
assign issue_request = input_fifo.valid & units_ready & ~unit_stall & (inflight_count < LS_OUTPUT_BUFFER_DEPTH);
assign issue_request = input_fifo.valid & units_ready & (inflight_count < 2) & ~unit_stall;
assign load_complete = data_valid;
generate if (USE_D_SCRATCH_MEM) begin
@ -180,7 +182,7 @@ module load_store_unit (
* 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), .*);
) ls_input_fifo (.fifo(input_fifo), .*);
assign input_fifo.data_in = ls_inputs;
assign input_fifo.push = ls_ex.new_request_dec;
@ -224,15 +226,18 @@ module load_store_unit (
*/
always_comb begin
for (integer i = 0; i < XLEN/8; i = i+ 1) begin
be[i] = stage1.store && (
((stage1.fn3[1:0] == LS_W_fn3[1:0])) ||
((stage1.fn3[1:0] == LS_H_fn3[1:0]) && (virtual_address[1] == i[1])) ||
((stage1.fn3[1:0] == LS_B_fn3[1:0]) && (virtual_address[1:0] == i)));
case(stage1.fn3[1:0])
LS_B_fn3[1:0] : be[i] = stage1.store && (virtual_address[1:0] == i);
LS_H_fn3[1:0] : be[i] = stage1.store && (virtual_address[1] == i[1]);
LS_W_fn3[1:0] : be[i] = stage1.store;
default : be[i] = 0;
endcase
end
end
assign most_recent_load = data_valid ? final_load_data : previous_load;
assign stage1_raw_data = (stage1.load_store_forward | dcache_forward_data) ? most_recent_load : stage1.rs2;
assign stage1_raw_data = (stage1.load_store_forward | dcache_forward_data) ?
(data_valid ? final_load_data : previous_load) :
stage1.rs2;
//AMO identification for dcache
generate
@ -255,11 +260,12 @@ module load_store_unit (
assign d_inputs.store = stage1.store;
assign d_inputs.be = be;
assign d_inputs.fn3 = stage1.fn3;
always_comb begin
case(dcache_forward_data ? dcache_stage2_fn3[1:0] : stage1.fn3[1:0]) //<--011, 110, 111, 100, 101 unused
LS_B_fn3[1:0] : d_inputs.data_in = {4{stage1_raw_data[7:0]}};
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
default : d_inputs.data_in = stage1_raw_data;//LS_W_fn3
endcase
end
@ -267,7 +273,7 @@ module load_store_unit (
* Load attributes FIFO
*********************************/
taiga_fifo #(.DATA_WIDTH($bits(load_attributes_t)), .FIFO_DEPTH(ATTRIBUTES_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) attributes_fifo (.fifo(load_attributes), .*);
) 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;
@ -327,52 +333,57 @@ module load_store_unit (
unit_muxed_load_data |= unit_data_array[i];
end
//Byte select
//Byte/halfword select: assumes aligned operations
always_comb begin
aligned_load_data[31:16] = unit_muxed_load_data[31:16];
aligned_load_data[15:8] = stage2_attr.byte_addr[1] ? unit_muxed_load_data[31:24] : unit_muxed_load_data[15:8];
halfword_load_data = stage2_attr.byte_addr[1] ? unit_muxed_load_data[31:16] : unit_muxed_load_data[15:0];
case(stage2_attr.byte_addr)
2'b00 : aligned_load_data[7:0] = unit_muxed_load_data[7:0];
2'b01 : aligned_load_data[7:0] = unit_muxed_load_data[15:8];
2'b10 : aligned_load_data[7:0] = unit_muxed_load_data[23:16];
2'b11 : aligned_load_data[7:0] = unit_muxed_load_data[31:24];
2'b00 : byte_load_data = unit_muxed_load_data[7:0];
2'b01 : byte_load_data = unit_muxed_load_data[15:8];
2'b10 : byte_load_data = unit_muxed_load_data[23:16];
2'b11 : byte_load_data = unit_muxed_load_data[31:24];
endcase
end
//Sign extending
always_comb begin
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;
unique case(stage2_attr.fn3)
LS_B_fn3 : final_load_data = 32'(signed'(byte_load_data));
LS_H_fn3 : final_load_data = 32'(signed'(halfword_load_data));
LS_W_fn3 : final_load_data = unit_muxed_load_data;
//unused 011
L_BU_fn3 : final_load_data = 32'(unsigned'(aligned_load_data[7:0]));
L_HU_fn3 : final_load_data = 32'(unsigned'(aligned_load_data[15:0]));
L_BU_fn3 : final_load_data = 32'(unsigned'(byte_load_data));
L_HU_fn3 : final_load_data = 32'(unsigned'(halfword_load_data));
//unused 110
//unused 111
default : final_load_data = aligned_load_data;
//default : final_load_data = unit_muxed_load_data;
endcase
end
always_ff @ (posedge clk) begin
if (data_valid)
previous_load <= final_load_data;
end
/*********************************
* Output FIFO
*********************************/
taiga_fifo #(.DATA_WIDTH(XLEN), .FIFO_DEPTH(LS_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
) output_fifo (.fifo(wb_fifo), .*);
logic[2:0] valid_chain;
assign wb_fifo.data_in = final_load_data;
assign wb_fifo.push = load_complete;
assign wb_fifo.pop = ls_wb.accepted;
assign ls_wb.rd = wb_fifo.data_out;
assign ls_wb.done = wb_fifo.early_valid;
//Occupancy Tracking
always_ff @ (posedge clk) begin
if (rst)
valid_chain <= 1;
else if (load_complete & ~ls_wb.accepted)
valid_chain <= {valid_chain[2-1:0], 1'b0};
else if (ls_wb.accepted & ~load_complete)
valid_chain <= {1'b0, valid_chain[2:1]};
end
assign ls_wb.early_done = 0;
always_ff @ (posedge clk) begin
if (load_complete) begin
previous_load <= final_load_data;
previous_load_r <= previous_load;
end
end
assign ls_wb.rd = valid_chain[2] ? previous_load_r : previous_load;
assign ls_wb.done_next_cycle = load_complete | valid_chain[2] | (valid_chain[1] & ~ls_wb.accepted);
assign ls_wb.done_on_first_cycle = 0;
/*********************************************/
endmodule

View file

@ -31,14 +31,14 @@ module mul_unit(
unit_writeback_interface.unit mul_wb
);
logic [65:0] result;
logic signed [65:0] result;
logic [1:0] mulh;
logic [1:0] advance;
logic [1:0] valid;
logic rs1_signed, rs2_signed;
logic [33:0] rs1_ext, rs2_ext;
logic [33:0] rs1_r, rs2_r;
logic signed [33:0] rs1_ext, rs2_ext;
logic signed [33:0] rs1_r, rs2_r;
//implementation
////////////////////////////////////////////////////
@ -71,7 +71,7 @@ module mul_unit(
mulh[0] <= ~(mul_inputs.op[1:0] == 0);
end
if (advance[1]) begin
result <= (rs1_r) * (rs2_r);
result <= signed'(rs1_r) * signed'(rs2_r);
mulh[1] <= mulh[0];
end
end
@ -81,8 +81,8 @@ module mul_unit(
assign mul_ex.ready = mul_wb.accepted | ~(&valid);
assign mul_wb.rd = mulh[1] ? result[63:32] : result[31:0];
assign mul_wb.done = valid[0] | (valid[1] & ~mul_wb.accepted);
assign mul_wb.early_done = 0;
assign mul_wb.done_next_cycle = valid[0] | (valid[1] & ~mul_wb.accepted);
assign mul_wb.done_on_first_cycle = 0;
////////////////////////////////////////////////////
endmodule

View file

@ -36,7 +36,6 @@ module normdiv
output logic complete
);
logic running;
logic terminate;
logic [C_WIDTH:0] new_PR;
@ -48,10 +47,10 @@ module normdiv
////////////////////////////////////////////////////
assign new_PR = {1'b0, PR} - {1'b0, B};
//Shift reg for
always_ff @ (posedge clk) begin
shift_count[0] <= start;
shift_count[31:1] <= shift_count[30:0];
terminate <= shift_count[31];
end
always_ff @ (posedge clk) begin
@ -74,23 +73,24 @@ module normdiv
assign R = PR[C_WIDTH:1];
always_ff @ (posedge clk) begin
if (rst) begin
running <= 0;
complete <= 0;
end
if (rst)
terminate <= 0;
else begin
if (start) begin
running <= 1;
complete <= 0;
end
else if (running & terminate) begin
running <= 0;
if (start)
terminate <= 0;
if (shift_count[31])
terminate <= 1;
end
end
always_ff @ (posedge clk) begin
if (rst)
complete <= 0;
else begin
if (shift_count[31])
complete <= 1;
end
else if (ack) begin
running <= 0;
else if (ack)
complete <= 0;
end
end
end

92
core/one_hot_occupancy.sv Normal file
View file

@ -0,0 +1,92 @@
/*
* 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::*;
module one_hot_occupancy #(parameter DEPTH = 2)
(
input logic clk,
input logic rst,
input logic push,
input logic pop,
output logic early_full,
output logic full,
output logic empty,
output logic valid,
output logic early_valid,
output logic two_plus
);
logic[DEPTH:0] valid_chain;
//Occupancy Tracking
always_ff @ (posedge clk) begin
if (rst)
valid_chain <= 1;
else if (push & ~pop)
valid_chain <= {valid_chain[DEPTH-1:0], 1'b0};
else if (pop & ~push)
valid_chain <= {1'b0, valid_chain[DEPTH:1]};
end
assign empty = valid_chain[0];
assign valid = ~valid_chain[0];
assign full = valid_chain[DEPTH];
// always_ff @ (posedge clk) begin
// if (rst)
// early_full <= 0;
// else if (push & ~pop & valid_chain[DEPTH-2])
// early_full <= 1;
// else if (pop & ~push & valid_chain[DEPTH-1])
// early_full <= 0;
// end
assign early_full = valid_chain[DEPTH-1] | valid_chain[DEPTH];
//pushing, or more than one, or at least one and not popping
always_ff @ (posedge clk) begin
if (rst)
two_plus <= 0;
else if ((valid & push) & ~pop)
two_plus <= 1;
else if (~push & (two_plus & pop))
two_plus <= 0;
end
// assign two_plus = ~valid_chain[0] & ~valid_chain[1];
assign early_valid = push | (two_plus) | (valid & ~pop);
////////////////////////////////////////////////////
//Assertions
always_ff @ (posedge clk) begin
assert (!(~rst & valid_chain[DEPTH] & push)) else $error("overflow");
assert (!(~rst & valid_chain[0] & pop)) else $error("underflow");
end
endmodule

View file

@ -27,20 +27,18 @@ module taiga (
input logic clk,
input logic rst,
bram_interface.user instruction_bram,
bram_interface.user data_bram,
local_memory_interface.master instruction_bram,
local_memory_interface.master data_bram,
axi_interface.master m_axi,
avalon_interface.master m_avalon,
l2_requester_interface.requester l2,
input logic interrupt,
//debug
output logic[31:0] dec_pc_debug,
output logic[31:0] if2_pc_debug,
output logic[31:0] dec_pc_debug
input logic interrupt
);
l1_arbiter_request_interface l1_request[L1_CONNECTIONS-1:0]();
@ -72,9 +70,6 @@ module taiga (
id_generator_interface id_gen();
unit_writeback_interface unit_wb [NUM_WB_UNITS-1:0]();
//writeback_unit_interface unit_wb();
register_file_writeback_interface rf_wb();
csr_exception_interface csr_exception();
@ -110,12 +105,11 @@ module taiga (
logic instruction_issued_no_rd;
logic instruction_complete;
assign instruction_issued = dec_advance;
assign if2_pc_debug = if2_pc;
assign dec_pc_debug = dec_pc;
assign instruction_issued = dec_advance;
/*************************************
* Memory Interface
@ -154,14 +148,6 @@ 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

@ -41,33 +41,24 @@ package taiga_config;
parameter USE_AMO = 0;
parameter NUM_WB_UNITS = 6;
parameter NUM_WB_UNITS = 4 + USE_MUL + USE_DIV;
parameter WB_UNITS_WIDTH = $clog2(NUM_WB_UNITS);
typedef enum {//bit [WB_UNITS_WIDTH-1:0] {
ALU_UNIT_ID = 0,
BRANCH_UNIT_ID=1,
CSR_UNIT_ID = 2,
LS_UNIT_ID = 3,
MUL_UNIT_ID = 4,
DIV_UNIT_ID = 5,
CUSTOM_ID_0 = 6,
CUSTOM_ID_1 = 7,
CUSTOM_ID_2 = 8,
CUSTOM_ID_3 = 9
} unit_ids;
typedef logic[WB_UNITS_WIDTH-1:0] unit_ids;
parameter ALU_UNIT_ID = 0;
parameter BRANCH_UNIT_ID = 1;
parameter CSR_UNIT_ID = 2;
parameter LS_UNIT_ID = 3;
parameter MUL_UNIT_ID = LS_UNIT_ID + USE_MUL;
parameter DIV_UNIT_ID = LS_UNIT_ID + USE_MUL + USE_DIV;
parameter INFLIGHT_QUEUE_DEPTH = 4;
parameter FETCH_BUFFER_DEPTH = 4;
parameter LS_INPUT_BUFFER_DEPTH = 4;
parameter LS_OUTPUT_BUFFER_DEPTH = 4;
parameter MUL_CYCLES = 1;
parameter MUL_OUTPUT_BUFFER_DEPTH = 2;
parameter DIV_INPUT_BUFFER_DEPTH = 2;
parameter DIV_OUTPUT_BUFFER_DEPTH = 2;
//Address space
parameter USE_I_SCRATCH_MEM = 1;
@ -94,10 +85,10 @@ package taiga_config;
//Caches
//Size in bytes: (DCACHE_LINES * DCACHE_WAYS * DCACHE_LINE_W * 4)
parameter USE_DCACHE = 0;
parameter DCACHE_LINES = 512;
parameter DCACHE_LINES = 256;
parameter DCACHE_WAYS = 2;
parameter DCACHE_LINE_ADDR_W = $clog2(DCACHE_LINES);
parameter DCACHE_LINE_W = 8; //In words
parameter DCACHE_LINE_W = 4; //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;
@ -110,14 +101,14 @@ package taiga_config;
//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 = 0;
parameter ICACHE_LINES = 128;
parameter ICACHE_LINES = 256;
parameter ICACHE_WAYS = 2;
parameter ICACHE_LINE_ADDR_W = $clog2(ICACHE_LINES);
parameter ICACHE_LINE_W = 8; //In words
parameter ICACHE_LINE_W = 4; //In words
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 = 1;
parameter USE_BRANCH_PREDICTOR = 0;
parameter BRANCH_TABLE_ENTRIES = 512;
parameter RAS_DEPTH = 8;

View file

@ -34,42 +34,31 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
fifo_interface.structure fifo
);
logic[DATA_WIDTH-1:0] lut_ram[FIFO_DEPTH-1:0];
(* ramstyle = "MLAB, no_rw_check" *) 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
one_hot_occupancy #(.DEPTH(FIFO_DEPTH)) occupancy_tracking
(
.push(fifo.push), .pop(fifo.pop),
.early_full(fifo.early_full), .full(fifo.full),
.empty(fifo.empty), .valid(fifo.valid), .early_valid(fifo.early_valid), .two_plus(two_plus), .*
);
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
@ -81,7 +70,6 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
write_index <= write_index + fifo.push;
end
end
assign fifo.data_out = lut_ram[read_index];
always_ff @ (posedge clk) begin
@ -94,13 +82,22 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
////////////////////////////////////////////////////
//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
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;
else if ((fifo.valid & fifo.push) & ~fifo.pop)
read_index <= read_index + 1;
else if (~fifo.push & (two_plus & fifo.pop))
read_index <= read_index - 1;
end
assign fifo.data_out = shift_reg[read_index];
@ -110,7 +107,7 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
shift_reg[0] <= fifo.data_in;
end
for (i=1 ; i < FIFO_DEPTH; i++) begin : shift_reg_gen
for (i=1 ; i < FIFO_DEPTH; i++) begin : taiga_fifo_shift_reg_gen
always_ff @ (posedge clk) begin
if (fifo.push)
shift_reg[i] <= shift_reg[i-1];
@ -122,7 +119,7 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
////////////////////////////////////////////////////
//Non-muxed output version
generate if (FIFO_TYPE == NON_MUXED_OUTPUT_FIFO) begin
////////////////////////////////////////////////////
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (rst)
@ -133,7 +130,7 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
assign fifo.data_out = shift_reg[0];
for (i=0 ; i <FIFO_DEPTH; i++) begin : new_reg_non_muxed_gen
for (i=0 ; i <FIFO_DEPTH; i++) begin : taiga_fifo_new_reg_non_muxed_gen
always_comb begin
if (fifo.push && write_index == i)
shift_reg_new[i] = fifo.data_in;
@ -146,7 +143,7 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
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
for (i=0 ; i < FIFO_DEPTH-1; i++) begin : taiga_fifo_shift_reg_non_muxed_gen
always_ff @ (posedge clk) begin
if (fifo.pop)
shift_reg[i] <= shift_reg_new[i+1];
@ -157,12 +154,6 @@ module taiga_fifo #(parameter DATA_WIDTH = 42, parameter FIFO_DEPTH = 4, paramet
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

@ -67,6 +67,20 @@ package taiga_types;
AND_fn3 = 3'b111
} fn3_arith_t;
typedef enum bit [1:0] {
ALU_ADD_SUB = 2'b00,
ALU_LOGIC = 2'b01,
ALU_SLT = 2'b10,
ALU_SHIFT =2'b11
} alu_op_t;
typedef enum bit [1:0] {
ALU_XOR = 2'b00,
ALU_OR = 2'b01,
ALU_AND = 2'b10,
ALU_ADD_SUB2 = 2'b11
} alu_logicop_t;
typedef enum bit [2:0] {
LS_B_fn3 = 3'b000,
LS_H_fn3 = 3'b001,
@ -228,21 +242,6 @@ package taiga_types;
M_EXTERNAL_INTERRUPT = 4'd11
} interrupt_code_t;
typedef enum bit [1:0] {
ALU_SLT = 2'b00,
ALU_SHIFTR = 2'b01,
ALU_SHIFT =2'b10,
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;
@ -262,13 +261,12 @@ package taiga_types;
typedef struct packed{
logic [XLEN-1:0] in1;
logic [XLEN-1:0] in2;
logic [XLEN:0] in1;//contains sign padding bit for slt operation
logic [XLEN:0] in2;//contains sign padding bit for slt operation
logic subtract;
logic arith;
logic [XLEN-1:0] shifter_in;
logic sltu;
logic [1:0] logic_op;
logic arith;//contains sign padding bit for arithmetic shift right operation
logic lshift;
logic [2:0] fn3;
logic [1:0] op;
}alu_inputs_t;
@ -337,6 +335,7 @@ package taiga_types;
logic [XLEN-1:0] rs1;
logic [XLEN-1:0] rs2;
logic [1:0] op;
logic skip_algo;
logic reuse_result;
logic div_zero;
} div_inputs_t;
@ -358,7 +357,7 @@ package taiga_types;
logic con;
} to_l1_arbiter_packet;
typedef struct {
typedef struct packed {
logic [31:0] addr;
logic load;
logic store;

View file

@ -35,26 +35,29 @@ module write_back(
output logic instruction_complete
);
logic [NUM_WB_UNITS-1:0] early_done;
logic [NUM_WB_UNITS-1:0] done;
logic [NUM_WB_UNITS-1:0] done_on_first_cycle;
logic [NUM_WB_UNITS-1:0] done_next_cycle;
logic selected_unit_done;
logic selected_unit_done_next_cycle;
logic entry_found;
logic [NUM_WB_UNITS-1:0] accepted;
logic [NUM_WB_UNITS-1:0] new_accepted;
logic [XLEN-1:0] rd [NUM_WB_UNITS-1:0];
logic [4:0] rd_addr, rd_addr_r;
logic rd_addr_not_zero;
logic [WB_UNITS_WIDTH-1:0] unit_id, unit_id_r;
instruction_id_t issue_id, issue_id_r;
int iq_index;
//Re-assigning interface inputs to array types so that they can be dynamically indexed
genvar i;
generate
for (i=0; i< NUM_WB_UNITS; i++) begin : interface_to_array_g
assign done[i] = unit_wb[i].done;
assign early_done[i] = unit_wb[i].early_done;
assign done_next_cycle[i] = unit_wb[i].done_next_cycle;
assign done_on_first_cycle[i] = unit_wb[i].done_on_first_cycle;
assign rd[i] = unit_wb[i].rd;
assign unit_wb[i].accepted = accepted[i];
end
@ -67,17 +70,17 @@ module write_back(
always_comb begin
entry_found = 0;
iq.pop = 0;
selected_unit_done = 0;
selected_unit_done_next_cycle = 0;
for (int i=INFLIGHT_QUEUE_DEPTH; i>0; i--) begin
unit_id = iq.data_out[i].unit_id;
issue_id = iq.data_out[i].id;
for (iq_index=INFLIGHT_QUEUE_DEPTH; iq_index>0; iq_index--) begin
unit_id = iq.data_out[iq_index].unit_id;
issue_id = iq.data_out[iq_index].id;
if (iq.valid[i]) begin
selected_unit_done = done[iq.data_out[i].unit_id];
iq.pop[i] = done[iq.data_out[i].unit_id];
if (iq.valid[iq_index]) begin
selected_unit_done_next_cycle = done_next_cycle[unit_id];
iq.pop[iq_index] = selected_unit_done_next_cycle;
if (inorder | (~inorder & done[iq.data_out[i].unit_id])) begin
if (inorder | (~inorder & selected_unit_done_next_cycle)) begin
entry_found = 1;
break;
end
@ -87,23 +90,30 @@ module write_back(
//Access rd_addr table in inflight_queue
iq.wb_id = issue_id;
rd_addr = iq.wb_rd_addr;
rd_addr_not_zero = |rd_addr;//iq.wb_uses_rd;
//No valid completing instructions in queue, check for new issues.
if (~entry_found) begin
unit_id = iq.data_out[0].unit_id;
issue_id = iq.data_out[0].id;
rd_addr = iq.future_rd_addr;
rd_addr_not_zero = iq.uses_rd;
//Pop and unit done only if valid issue
selected_unit_done = early_done[iq.data_out[0].unit_id] & iq.valid[0];
iq.pop[0] = early_done[iq.data_out[0].unit_id] & iq.valid[0];
if (iq.valid[0]) begin
selected_unit_done_next_cycle = done_on_first_cycle[unit_id];
iq.pop[0] = selected_unit_done_next_cycle;
end
end
end
always_ff @(posedge clk) begin
if (rst)
instruction_complete <= 0;
else
instruction_complete <= selected_unit_done;
instruction_complete <= selected_unit_done_next_cycle;
end
always_ff @(posedge clk) begin
@ -120,23 +130,24 @@ module write_back(
if (rst)
rf_wb.valid_write <= 0;
else
rf_wb.valid_write <= selected_unit_done && (rd_addr != 0);
rf_wb.valid_write <= selected_unit_done_next_cycle & rd_addr_not_zero;
end
assign rf_wb.rd_addr_early = rd_addr;
assign rf_wb.id_early = issue_id;
assign rf_wb.valid_write_early = selected_unit_done;
assign rf_wb.valid_write_early = selected_unit_done_next_cycle;
generate
for (i=0; i<NUM_WB_UNITS; i=i+1) begin : wb_mux
always_ff @(posedge clk) begin
if (rst)
accepted[i] <= 0;
else
accepted[i] <= selected_unit_done && (unit_id == i);
end
end
endgenerate
always_comb begin
new_accepted = 0;
new_accepted[unit_id] = selected_unit_done_next_cycle;
end
always_ff @(posedge clk) begin
if (rst)
accepted <= 0;
else
accepted <= new_accepted;
end
//ID generator signals
assign id_gen.complete = instruction_complete;

View file

@ -222,8 +222,8 @@ module taiga_wrapper (
assign m_axi.bresp = bus_axi_bresp;
bram_interface instruction_bram();
bram_interface data_bram();
local_memory_interface instruction_bram();
local_memory_interface data_bram();
taiga cpu(.*, .l2(l2[0]));
@ -238,15 +238,15 @@ module taiga_wrapper (
arm proc(.*);
byte_en_BRAM #(8192*4, "/home/ematthew/Research/RISCV/software2/riscv-tools/riscv-tests/benchmarks/dhrystone.riscv.hw_init", 1) inst_data_ram (
byte_en_BRAM #(8192, "/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*4)- 1:0]),
.addr_a(instruction_bram.addr[$clog2(8192)- 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*4)- 1:0]),
.addr_b(data_bram.addr[$clog2(8192)- 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/Research/RISCV/software2/riscv-tools/riscv-tests/benchmarks/sqrt.riscv.sim_init"
`define MEMORY_FILE "/home/ematthew/Research/RISCV/software2/riscv-tools/riscv-tests/benchmarks/fft.riscv.sim_init"
`define UART_LOG "/home/ematthew/uart.log"
module taiga_tb ( );
@ -164,8 +164,8 @@ module taiga_tb ( );
assign clk = simulator_clk;
assign rst = processor_reset;
bram_interface instruction_bram();
bram_interface data_bram();
local_memory_interface instruction_bram();
local_memory_interface data_bram();
axi_interface m_axi();
avalon_interface m_avalon();
@ -238,7 +238,7 @@ module taiga_tb ( );
end
do_reset();
#3600000;
#1500000;
$fclose(output_file);
$finish;
end

View file

@ -15,15 +15,15 @@
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="4143000000fs"></ZoomStartTime>
<ZoomEndTime time="4445500001fs"></ZoomEndTime>
<Cursor1Time time="4293000000fs"></Cursor1Time>
<ZoomStartTime time="0fs"></ZoomStartTime>
<ZoomEndTime time="11193913045fs"></ZoomEndTime>
<Cursor1Time time="3537100000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="297"></NameColumnWidth>
<ValueColumnWidth column_width="87"></ValueColumnWidth>
<ValueColumnWidth column_width="79"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="183" />
<WVObjectSize size="188" />
<wvobject type="logic" fp_name="/taiga_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
@ -99,6 +99,26 @@
<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_tb/uut/fetch_block/inflight_count">
<obj_property name="ElementShortName">inflight_count[8:0]</obj_property>
<obj_property name="ObjectShortName">inflight_count[8:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/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="array" fp_name="/taiga_tb/uut/inst_buffer/ib_fifo_block/valid_chain">
<obj_property name="ElementShortName">valid_chain[256:0]</obj_property>
<obj_property name="ObjectShortName">valid_chain[256:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/fetch_block/stage2_cache_access">
<obj_property name="ElementShortName">stage2_cache_access</obj_property>
<obj_property name="ObjectShortName">stage2_cache_access</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/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_tb/uut/fetch_block/bram_access">
<obj_property name="ElementShortName">bram_access</obj_property>
<obj_property name="ObjectShortName">bram_access</obj_property>
@ -321,8 +341,8 @@
<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="ElementShortName">in_use_by[0:31][2:0]</obj_property>
<obj_property name="ObjectShortName">in_use_by[0:31][2:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/write_back_mux/entry_found">
@ -342,8 +362,8 @@
<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[4:0][4:0]</obj_property>
<obj_property name="ObjectShortName">shift_reg[4:0][4:0]</obj_property>
<obj_property name="ElementShortName">shift_reg[8:0][5:0]</obj_property>
<obj_property name="ObjectShortName">shift_reg[8:0][5: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>
@ -361,9 +381,17 @@
<obj_property name="ElementShortName">ls_inputs</obj_property>
<obj_property name="ObjectShortName">ls_inputs</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>
<obj_property name="ObjectShortName">issue_request</obj_property>
</wvobject>
<wvobject type="array" fp_name="/taiga_tb/uut/load_store_unit_block/inflight_count">
<obj_property name="ElementShortName">inflight_count[1:0]</obj_property>
<obj_property name="ObjectShortName">inflight_count[1:0]</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>
<obj_property name="ElementShortName">read_index[1:0]</obj_property>
<obj_property name="ObjectShortName">read_index[1: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>
@ -390,33 +418,11 @@
<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>
<obj_property name="ObjectShortName">issue_request</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/taiga_tb/uut/load_store_unit_block/load_complete">
<obj_property name="ElementShortName">load_complete</obj_property>
<obj_property name="ObjectShortName">load_complete</obj_property>
@ -481,10 +487,6 @@
<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>