mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
replacing onehot with a new version
This commit is contained in:
parent
8e16111e91
commit
3dd7e7a217
8 changed files with 56 additions and 165 deletions
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2024 Chris Keilbart
|
||||
*
|
||||
* 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):
|
||||
* Chris Keilbart <ckeilbar@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module one_hot_mux
|
||||
#(
|
||||
parameter OPTIONS = 5,
|
||||
parameter type DATA_TYPE = logic
|
||||
)
|
||||
(
|
||||
//Only used for assertions
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
||||
input logic[OPTIONS-1:0] one_hot,
|
||||
input DATA_TYPE[OPTIONS-1:0] choices,
|
||||
output DATA_TYPE sel
|
||||
);
|
||||
|
||||
//Casting to eliminate warnings
|
||||
typedef logic[$bits(DATA_TYPE)-1:0] casted_t;
|
||||
casted_t[OPTIONS-1:0] choices_casted;
|
||||
casted_t sel_casted;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
//Cheaper than converting ohot -> int and indexing
|
||||
always_comb begin
|
||||
for (int i = 0; i < OPTIONS; i++)
|
||||
choices_casted[i] = casted_t'(choices[i]);
|
||||
sel = DATA_TYPE'(sel_casted);
|
||||
end
|
||||
|
||||
generate if (OPTIONS == 1) begin : gen_no_mux
|
||||
assign sel_casted = choices_casted[0];
|
||||
end else begin : gen_mux
|
||||
always_comb begin
|
||||
sel_casted = '0;
|
||||
for (int i = 0; i < OPTIONS; i++)
|
||||
if (one_hot[i]) sel_casted |= choices_casted[i];
|
||||
end
|
||||
end endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
//Support inputs that aren't one hot as long as they are identical
|
||||
logic supported_inputs;
|
||||
logic saw_first;
|
||||
casted_t queried_input;
|
||||
always_comb begin
|
||||
supported_inputs = 1;
|
||||
saw_first = 0;
|
||||
queried_input = 'x;
|
||||
for (int i = 0; i < OPTIONS; i++) begin
|
||||
if (one_hot[i]) begin
|
||||
supported_inputs |= ~saw_first | (queried_input == choices_casted[i]);
|
||||
saw_first = 1;
|
||||
queried_input = choices_casted[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ohot_assertion:
|
||||
assert property (@(posedge clk) disable iff (rst) supported_inputs)
|
||||
else $error("Selection mux not one hot");
|
||||
|
||||
endmodule
|
|
@ -358,7 +358,7 @@ generate if (CONFIG.MODES != BARE) begin : gen_gc_m_mode
|
|||
logic [NUM_EXCEPTION_SOURCES-1:0][31:0] exception_tval;
|
||||
logic [NUM_EXCEPTION_SOURCES-1:0][31:0] exception_pc;
|
||||
logic [NUM_EXCEPTION_SOURCES-1:0] exception_discard;
|
||||
logic [31:0] muxed_exception_pc;
|
||||
logic [$clog2(NUM_EXCEPTION_SOURCES > 1 ? NUM_EXCEPTION_SOURCES : 2)-1:0] exception_source;
|
||||
|
||||
for (genvar i = 0; i < NUM_EXCEPTION_SOURCES; i++) begin : gen_unpacking
|
||||
assign exception_valid[i] = exception[i].valid;
|
||||
|
@ -368,28 +368,18 @@ generate if (CONFIG.MODES != BARE) begin : gen_gc_m_mode
|
|||
assign exception_pc[i] = exception[i].pc;
|
||||
end
|
||||
|
||||
one_hot_to_integer #(.C_WIDTH(NUM_EXCEPTION_SOURCES)) src_mux (
|
||||
.one_hot(exception_valid),
|
||||
.int_out(exception_source)
|
||||
);
|
||||
|
||||
assign gc.exception.valid = |exception_valid;
|
||||
assign gc.exception.code = exception_code[exception_source];
|
||||
assign gc.exception.tval = exception_tval[exception_source];
|
||||
assign gc.exception.pc = |exception_valid ? exception_pc[exception_source] : issue_stage.pc;
|
||||
assign gc.exception.valid = |exception_valid;
|
||||
assign gc.exception.source = exception_valid;
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_EXCEPTION_SOURCES), .DATA_TYPE(exception_code_t)) code_mux (
|
||||
.one_hot(exception_valid),
|
||||
.choices(exception_code),
|
||||
.sel(gc.exception.code),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_EXCEPTION_SOURCES), .DATA_TYPE(logic[31:0])) tval_mux (
|
||||
.one_hot(exception_valid),
|
||||
.choices(exception_tval),
|
||||
.sel(gc.exception.tval),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_EXCEPTION_SOURCES), .DATA_TYPE(logic[31:0])) pc_mux (
|
||||
.one_hot(exception_valid),
|
||||
.choices(exception_pc),
|
||||
.sel(muxed_exception_pc),
|
||||
.*);
|
||||
assign gc.exception.pc = |exception_valid ? muxed_exception_pc : issue_stage.pc;
|
||||
|
||||
assign interrupt_taken = interrupt_pending & (next_state == PRE_ISSUE_FLUSH) & ~(gc.exception.valid) & ~csr_frontend_flush;
|
||||
|
||||
//Writeback and rename handling
|
||||
|
|
|
@ -72,30 +72,22 @@ module amo_unit
|
|||
amo_t selected_op;
|
||||
logic[31:0] selected_rs1;
|
||||
logic[31:0] selected_rs2;
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_UNITS), .DATA_TYPE(amo_t)) op_mux (
|
||||
.one_hot(rmw_valid),
|
||||
.choices(op),
|
||||
.sel(selected_op),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_UNITS), .DATA_TYPE(logic[31:0])) rs1_mux (
|
||||
.one_hot(rmw_valid),
|
||||
.choices(rs1),
|
||||
.sel(selected_rs1),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_UNITS), .DATA_TYPE(logic[31:0])) rs2_mux (
|
||||
.one_hot(rmw_valid),
|
||||
.choices(rs2),
|
||||
.sel(selected_rs2),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(NUM_UNITS), .DATA_TYPE(reservation_t)) reservation_mux (
|
||||
logic[$clog2(NUM_UNITS > 1 ? NUM_UNITS : 2)-1:0] reservation_int;
|
||||
logic[$clog2(NUM_UNITS > 1 ? NUM_UNITS : 2)-1:0] rmw_int;
|
||||
|
||||
one_hot_to_integer #(.C_WIDTH(NUM_UNITS)) reservation_conv (
|
||||
.one_hot(set_reservation),
|
||||
.choices(reservation),
|
||||
.sel(set_val),
|
||||
.*);
|
||||
.int_out(reservation_int)
|
||||
);
|
||||
assign set_val = reservation[reservation_int];
|
||||
|
||||
one_hot_to_integer #(.C_WIDTH(NUM_UNITS)) rmw_conv (
|
||||
.one_hot(rmw_valid),
|
||||
.int_out(rmw_int)
|
||||
);
|
||||
assign selected_op = op[rmw_int];
|
||||
assign selected_rs1 = rs1[rmw_int];
|
||||
assign selected_rs2 = rs2[rmw_int];
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//RISC-V LR-SC
|
||||
|
|
|
@ -524,6 +524,7 @@ module dcache_inv
|
|||
logic[CONFIG.DCACHE.WAYS-1:0][31:0] db_entries;
|
||||
logic[31:0] db_hit_entry;
|
||||
logic[CONFIG.DCACHE.WAYS-1:0][3:0] db_wbe_full;
|
||||
logic[$clog2(CONFIG.DCACHE.WAYS > 1 ? CONFIG.DCACHE.WAYS : 2)-1:0] hit_int;
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < CONFIG.DCACHE.WAYS; i++)
|
||||
|
@ -548,16 +549,11 @@ module dcache_inv
|
|||
.b_rdata(db_entries),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(
|
||||
.OPTIONS(CONFIG.DCACHE.WAYS),
|
||||
.DATA_TYPE(logic[31:0])
|
||||
) db_mux (
|
||||
.clk(clk),
|
||||
.rst(1'b1), //Disable the assertion
|
||||
one_hot_to_integer #(.C_WIDTH(CONFIG.DCACHE.WAYS)) hit_conv (
|
||||
.one_hot(hit_ohot),
|
||||
.choices(db_entries),
|
||||
.sel(db_hit_entry)
|
||||
.int_out(hit_int)
|
||||
);
|
||||
assign db_hit_entry = db_entries[hit_int];
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
|
@ -569,4 +565,8 @@ module dcache_inv
|
|||
assert property (@(posedge clk) disable iff (rst) mem.ack |-> mem.request)
|
||||
else $error("dcache received ack without a request");
|
||||
|
||||
// dcache_ohot_assertion:
|
||||
// assert property (@(posedge clk) disable iff (rst) ls.new_request |=> $onehot0(hit_ohot))
|
||||
// else $error("dcache hit multiple ways");
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -167,6 +167,7 @@ module dcache_noinv
|
|||
//Databank
|
||||
logic[CONFIG.DCACHE.WAYS-1:0][31:0] db_entries;
|
||||
logic[31:0] db_hit_entry;
|
||||
logic[$clog2(CONFIG.DCACHE.WAYS > 1 ? CONFIG.DCACHE.WAYS : 2)-1:0] hit_int;
|
||||
logic[CONFIG.DCACHE.WAYS-1:0] db_way;
|
||||
logic[CONFIG.DCACHE.WAYS-1:0][3:0] db_wbe_full;
|
||||
logic[31:0] db_wdata;
|
||||
|
@ -194,13 +195,11 @@ module dcache_noinv
|
|||
.b_rdata(db_entries),
|
||||
.*);
|
||||
|
||||
always_comb begin
|
||||
db_hit_entry = 'x;
|
||||
for (int i = 0; i < CONFIG.DCACHE.WAYS; i++) begin
|
||||
if (hit_ohot[i])
|
||||
db_hit_entry = db_entries[i];
|
||||
end
|
||||
end
|
||||
one_hot_to_integer #(.C_WIDTH(CONFIG.DCACHE.WAYS)) hit_conv (
|
||||
.one_hot(hit_ohot),
|
||||
.int_out(hit_int)
|
||||
);
|
||||
assign db_hit_entry = db_entries[hit_int];
|
||||
|
||||
//Arbiter response
|
||||
logic correct_word;
|
||||
|
@ -369,4 +368,8 @@ module dcache_noinv
|
|||
assert property (@(posedge clk) disable iff (rst) mem.ack |-> mem.request)
|
||||
else $error("dcache received ack without a request");
|
||||
|
||||
// dcache_ohot_assertion:
|
||||
// assert property (@(posedge clk) disable iff (rst) ls.new_request |=> $onehot0(hit_ohot))
|
||||
// else $error("dcache hit multiple ways");
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -77,7 +77,6 @@ module branch_predictor
|
|||
} branch_table_entry_t;
|
||||
|
||||
branch_table_entry_t [CONFIG.BP.WAYS-1:0] if_entry;
|
||||
branch_table_entry_t muxed_entry;
|
||||
branch_table_entry_t ex_entry;
|
||||
|
||||
typedef struct packed{
|
||||
|
@ -90,12 +89,12 @@ module branch_predictor
|
|||
logic branch_predictor_direction_changed;
|
||||
logic [31:0] new_jump_addr;
|
||||
logic [CONFIG.BP.WAYS-1:0][31:0] predicted_pc;
|
||||
logic [31:0] muxed_predicted_pc;
|
||||
|
||||
logic [CONFIG.BP.WAYS-1:0] tag_matches;
|
||||
logic [CONFIG.BP.WAYS-1:0] replacement_way;
|
||||
logic [CONFIG.BP.WAYS-1:0] tag_update_way;
|
||||
logic [CONFIG.BP.WAYS-1:0] target_update_way;
|
||||
logic [$clog2(CONFIG.BP.WAYS > 1 ? CONFIG.BP.WAYS : 2)-1:0] hit_way;
|
||||
logic tag_match;
|
||||
logic use_predicted_pc;
|
||||
|
||||
|
@ -138,33 +137,27 @@ module branch_predictor
|
|||
|
||||
assign tag_matches[i] = ({if_entry[i].valid, if_entry[i].tag} == {1'b1, addr_utils.getTag(bp.if_pc)});
|
||||
end
|
||||
|
||||
one_hot_mux #(.OPTIONS(CONFIG.BP.WAYS), .DATA_TYPE(branch_table_entry_t)) hit_mux (
|
||||
.one_hot(tag_matches),
|
||||
.choices(if_entry),
|
||||
.sel(muxed_entry),
|
||||
.*);
|
||||
|
||||
one_hot_mux #(.OPTIONS(CONFIG.BP.WAYS), .DATA_TYPE(logic[31:0])) pc_mux (
|
||||
.one_hot(tag_matches),
|
||||
.choices(predicted_pc),
|
||||
.sel(muxed_predicted_pc),
|
||||
.*);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Instruction Fetch Response
|
||||
one_hot_to_integer #(CONFIG.BP.WAYS)
|
||||
hit_way_conv (
|
||||
.one_hot(tag_matches),
|
||||
.int_out(hit_way)
|
||||
);
|
||||
|
||||
assign tag_match = |tag_matches;
|
||||
|
||||
assign use_predicted_pc = CONFIG.INCLUDE_BRANCH_PREDICTOR & tag_match;
|
||||
|
||||
//Predicted PC and whether the prediction is valid
|
||||
assign bp.predicted_pc = muxed_predicted_pc;
|
||||
assign bp.predicted_pc = predicted_pc[hit_way];
|
||||
assign bp.use_prediction = use_predicted_pc;
|
||||
assign bp.is_branch = muxed_entry.is_branch;
|
||||
assign bp.is_return = muxed_entry.is_return;
|
||||
assign bp.is_call = muxed_entry.is_call;
|
||||
assign bp.is_branch = if_entry[hit_way].is_branch;
|
||||
assign bp.is_return = if_entry[hit_way].is_return;
|
||||
assign bp.is_call = if_entry[hit_way].is_call;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Instruction Fetch metadata
|
||||
|
@ -183,7 +176,7 @@ module branch_predictor
|
|||
.raddr(br_results.id),
|
||||
.ram_write(bp.pc_id_assigned),
|
||||
.new_ram_data('{
|
||||
branch_predictor_metadata : muxed_entry.metadata,
|
||||
branch_predictor_metadata : if_entry[hit_way].metadata,
|
||||
branch_prediction_used : use_predicted_pc,
|
||||
branch_predictor_update_way : tag_match ? tag_matches : replacement_way
|
||||
}),
|
||||
|
|
|
@ -167,7 +167,7 @@ module renamer
|
|||
assign spec_table_next = spec_table_next_mux[spec_table_sel];
|
||||
|
||||
assign spec_table_read_addr[0] = spec_table_write_index;
|
||||
assign spec_table_read_addr[1+:READ_PORTS] = decode.rs_addr;
|
||||
assign spec_table_read_addr[1:READ_PORTS] = decode.rs_addr;
|
||||
|
||||
lutram_1w_mr #(
|
||||
.DATA_TYPE(spec_table_t),
|
||||
|
|
|
@ -15,7 +15,6 @@ core/common_components/ram/sdp_ram_padded.sv
|
|||
core/common_components/ram/tdp_ram.sv
|
||||
core/common_components/set_clr_reg_with_rst.sv
|
||||
core/common_components/one_hot_to_integer.sv
|
||||
core/common_components/one_hot_mux.sv
|
||||
core/common_components/cycler.sv
|
||||
core/common_components/lfsr.sv
|
||||
core/common_components/cva5_fifo.sv
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue