-
Notifications
You must be signed in to change notification settings - Fork 52
A-extension updates #780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A-extension updates #780
Changes from 4 commits
4548867
242887b
c336ac6
ded5311
fdb3afc
681de60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,7 +32,8 @@ | |
|
||
module cv32e40x_controller_bypass import cv32e40x_pkg::*; | ||
#( | ||
parameter int unsigned REGFILE_NUM_READ_PORTS = 2 | ||
parameter int unsigned REGFILE_NUM_READ_PORTS = 2, | ||
parameter bit A_EXT = 1'b0 | ||
) | ||
( | ||
// From decoder | ||
|
@@ -58,6 +59,11 @@ module cv32e40x_controller_bypass import cv32e40x_pkg::*; | |
input logic wb_ready_i, // WB stage is ready | ||
input logic csr_irq_enable_write_i, // WB is writing to a CSR that may enable an interrupt. | ||
|
||
// From LSU | ||
input lsu_atomic_e lsu_atomic_ex_i, | ||
input lsu_atomic_e lsu_atomic_wb_i, | ||
input logic lsu_bus_busy_i, | ||
|
||
// Controller Bypass outputs | ||
output ctrl_byp_t ctrl_byp_o | ||
); | ||
|
@@ -232,6 +238,24 @@ module cv32e40x_controller_bypass import cv32e40x_pkg::*; | |
end | ||
end | ||
|
||
generate | ||
if (A_EXT) begin : atomic_stall | ||
always_comb begin | ||
ctrl_byp_o.atomic_stall = 1'b0; | ||
|
||
// Stall EX for the following two scenarios | ||
// 1: There is an atomic instruction in EX while we have outstanding transactions on the bus | ||
// 2: There is any LSU instruction in EX while there is an outstanding atomic transfer in progress | ||
if ((id_ex_pipe_i.lsu_en && (lsu_atomic_ex_i != AT_NONE) && id_ex_pipe_i.instr_valid) || | ||
(id_ex_pipe_i.lsu_en && ex_wb_pipe_i.lsu_en && (lsu_atomic_wb_i != AT_NONE) && ex_wb_pipe_i.instr_valid)) begin | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (id_ex_pipe_i.lsu_en && ex_wb_pipe_i.lsu_en && (lsu_atomic_wb_i != AT_NONE) && ex_wb_pipe_i.instr_valid) -> There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated |
||
ctrl_byp_o.atomic_stall = lsu_bus_busy_i; | ||
end | ||
end | ||
end else begin : no_atomic_stall | ||
assign ctrl_byp_o.atomic_stall = 1'b0; | ||
end | ||
endgenerate | ||
|
||
assign ctrl_byp_o.id_stage_abort = ctrl_byp_o.deassert_we; | ||
|
||
// Forwarding control unit | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -643,7 +643,7 @@ module cv32e40x_controller_fsm import cv32e40x_pkg::*; | |
// Also halting EX if an offloaded instruction in WB may cause an exception, such that a following offloaded | ||
// instruction can correctly receive commit_kill. | ||
// Halting EX when an instruction in WB may cause an interrupt to become pending. | ||
ctrl_fsm_o.halt_ex = ctrl_byp_i.minstret_stall || ctrl_byp_i.xif_exception_stall || ctrl_byp_i.irq_enable_stall || ctrl_byp_i.mnxti_ex_stall; | ||
ctrl_fsm_o.halt_ex = ctrl_byp_i.minstret_stall || ctrl_byp_i.xif_exception_stall || ctrl_byp_i.irq_enable_stall || ctrl_byp_i.mnxti_ex_stall || ctrl_byp_i.atomic_stall; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update above comments with reason why atomic stall is needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added comment |
||
ctrl_fsm_o.halt_wb = 1'b0; | ||
ctrl_fsm_o.halt_limited_wb = 1'b0; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
|
||
// Control outputs | ||
output logic busy_o, | ||
output logic bus_busy_o, // There are outstanding OBI transactions | ||
output logic interruptible_o, | ||
|
||
// Trigger match input | ||
|
@@ -60,6 +61,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
output logic lsu_split_0_o, // Misaligned access is split in two transactions (to controller) | ||
output logic lsu_first_op_0_o, // First operation is active in EX | ||
output logic lsu_last_op_0_o, // Last operation is active in EX | ||
output lsu_atomic_e lsu_atomic_0_o, // IS there an atomic in EX, and of which type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IS -> Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
|
||
// outputs to trigger module | ||
output logic [31:0] lsu_addr_o, | ||
|
@@ -71,6 +73,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
output logic [31:0] lsu_rdata_1_o, // LSU read data | ||
output mpu_status_e lsu_mpu_status_1_o, // MPU (PMA) status, response/WB timing. To controller and wb_stage | ||
output logic lsu_wpt_match_1_o, // Address match trigger, WB timing. | ||
output lsu_atomic_e lsu_atomic_1_o, // Is there an atomic in WB, and of which type. | ||
|
||
// Handshakes | ||
input logic valid_0_i, // Handshakes for first LSU stage (EX) | ||
|
@@ -105,6 +108,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
logic mpu_trans_valid; | ||
logic mpu_trans_ready; | ||
logic mpu_trans_pushpop; | ||
logic mpu_trans_atomic; | ||
obi_data_req_t mpu_trans; | ||
|
||
// Transaction response | ||
|
@@ -392,10 +396,45 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
end | ||
end | ||
|
||
// output to register file | ||
// Always rdata_ext regardless of split accesses | ||
// Output will be valid (valid_1_o) only for the last phase of split access. | ||
assign lsu_rdata_1_o = rdata_ext; | ||
// Set rdata output and atomic type output depending on A_EXT | ||
Silabs-ArjanB marked this conversation as resolved.
Show resolved
Hide resolved
|
||
generate | ||
if (A_EXT) begin : a_ext | ||
lsu_atomic_e lsu_atomic_q; | ||
|
||
always_ff @(posedge clk, negedge rst_n) | ||
begin | ||
if (rst_n == 1'b0) begin | ||
lsu_atomic_q <= AT_NONE; | ||
end else if (ctrl_update) begin // request was granted, we wait for rvalid and can continue to WB | ||
if (xif_req) begin | ||
lsu_atomic_q <= AT_NONE; | ||
end else begin | ||
// Set type of atomic instruction in WB, if any. | ||
lsu_atomic_q <= lsu_atomic_0_o; | ||
end | ||
end | ||
end | ||
|
||
assign lsu_atomic_0_o = !trans.atop[5] ? AT_NONE : | ||
(trans.atop[4:0] == 5'h2) ? AT_LR : | ||
(trans.atop[4:0] == 5'h3) ? AT_SC : | ||
AT_AMO; | ||
assign lsu_atomic_1_o = lsu_atomic_q; | ||
|
||
// SC.W must write 0 to rd on success, and 1 on failure. All other instructions including AMO write the response data. | ||
assign lsu_rdata_1_o = (lsu_atomic_q == AT_SC) ? {{31{1'b0}}, !resp.bus_resp.exokay} : rdata_ext; | ||
|
||
end else begin : no_a_ext | ||
// A_EXT not enabled, tie off outputs. | ||
assign lsu_atomic_0_o = AT_NONE; | ||
assign lsu_atomic_1_o = AT_NONE; | ||
|
||
// output to register file | ||
// Always rdata_ext regardless of split accesses | ||
// Output will be valid (valid_1_o) only for the last phase of split access. | ||
assign lsu_rdata_1_o = rdata_ext; | ||
end | ||
endgenerate | ||
|
||
// misaligned_access is high for both transfers of a misaligned transfer | ||
// TODO: Give MPU a separate modified_access_i input | ||
|
@@ -717,6 +756,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
////////////////////////////////////////////////////////////////////////////// | ||
// MPU | ||
////////////////////////////////////////////////////////////////////////////// | ||
assign mpu_trans_atomic = |(mpu_trans.atop); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only use bit 5 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
|
||
cv32e40x_mpu | ||
#( | ||
|
@@ -734,7 +774,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
( | ||
.clk ( clk ), | ||
.rst_n ( rst_n ), | ||
.atomic_access_i ( 1'b0 ), // TODO:OE update to support atomic PMA checks | ||
.atomic_access_i ( mpu_trans_atomic ), | ||
.misaligned_access_i ( misaligned_access ), | ||
|
||
.core_one_txn_pend_n ( cnt_is_one_next ), | ||
|
@@ -764,6 +804,7 @@ module cv32e40x_load_store_unit import cv32e40x_pkg::*; | |
(.clk ( clk ), | ||
.rst_n ( rst_n ), | ||
.busy_o ( filter_resp_busy ), | ||
.bus_busy_o ( bus_busy_o ), | ||
|
||
.valid_i ( filter_trans_valid ), | ||
.ready_o ( filter_trans_ready ), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,6 +118,14 @@ module cv32e40x_pma import cv32e40x_pkg::*; | |
pma_err_o = 1'b1; | ||
end | ||
|
||
// Check that atomic accesses are not misaligned | ||
// Not strictly at part of the PMA, but reusing the PMA logic for flagging errors | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. at -> a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
// and consume transactions rather than making separate logic in the LSU. Uses the same exception | ||
// codes as PMA errors. | ||
if (atomic_access_i && misaligned_access_i) begin | ||
pma_err_o = 1'b1; | ||
end | ||
|
||
// Instruction fetches only allowed in main memory | ||
if (instr_fetch_access_i && !pma_cfg.main) begin | ||
pma_err_o = 1'b1; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent everything 2 positions to the right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indented