Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions rtl/verilog/mor1kx_ctrl_cappuccino.v
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ module mor1kx_ctrl_cappuccino
/* Wires for SPR management */
wire spr_access_valid;
wire spr_we;
wire spr_write_authorized;
wire spr_read;
wire spr_ack;
wire [OPTION_OPERAND_WIDTH-1:0] spr_write_dat;
Expand Down Expand Up @@ -1206,13 +1207,17 @@ module mor1kx_ctrl_cappuccino
assign spr_read_access = (ctrl_op_mfspr_i | (du_access & !du_we_i));
assign spr_write_access = (ctrl_op_mtspr_i | (du_access & du_we_i));

/* Check privilege before allowing an SPR write. */
assign spr_write_authorized = (ctrl_op_mtspr_i & spr_sr[`OR1K_SPR_SR_SM]) |
(du_access & du_we_i);

assign spr_write_dat = du_access ? du_dat_i : ctrl_rfb_i;
assign spr_we = spr_write_access & spr_access_valid;
assign spr_we = spr_write_authorized & spr_access_valid;
assign spr_read = spr_read_access & spr_access_valid;

/* A bus out to other units that live outside of the control unit */
assign spr_bus_addr_o = spr_addr;
assign spr_bus_we_o = spr_write_access & spr_access_valid & spr_bus_access;
assign spr_bus_we_o = spr_write_authorized & spr_access_valid & spr_bus_access;
assign spr_bus_stb_o = (spr_read_access | spr_write_access) &
spr_access_valid & spr_bus_access;
assign spr_bus_dat_o = spr_write_dat;
Expand Down Expand Up @@ -1656,6 +1661,11 @@ endgenerate
if (spr_bus_we_o)
assert (spr_we);

// User-mode l.mtspr must never enable an SPR write.
always @*
if (ctrl_op_mtspr_i & !du_access & !spr_sr[`OR1K_SPR_SR_SM])
assert (!spr_we & !spr_bus_we_o);

always @(posedge clk) begin
if (f_past_valid && !$past(rst) && $past(exception_re)) begin
assert (spr_sr[`OR1K_SPR_SR_SM]);
Expand Down
9 changes: 7 additions & 2 deletions rtl/verilog/mor1kx_ctrl_espresso.v
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ module mor1kx_ctrl_espresso
wire spr_group_present;
wire [3:0] spr_group;
wire spr_we;
wire spr_write_authorized;
wire spr_read;
wire [OPTION_OPERAND_WIDTH-1:0] spr_write_dat;
wire [11:0] spr_access_ack;
Expand Down Expand Up @@ -1067,13 +1068,17 @@ module mor1kx_ctrl_espresso
assign spr_read_access = (op_mfspr | (du_access & !du_we_i));
assign spr_write_access = ((execute_done & op_mtspr) | (du_access & du_we_i));

/* Check privilege before allowing an SPR write. */
assign spr_write_authorized = (op_mtspr & spr_sr[`OR1K_SPR_SR_SM]) |
(du_access & du_we_i);

assign spr_write_dat = du_access ? du_dat_i : b;
assign spr_we = spr_write_access & spr_group_present;
assign spr_we = spr_write_authorized & spr_group_present;
assign spr_read = spr_read_access & spr_group_present;

/* A bus out to other units that live outside of the control unit */
assign spr_bus_addr_o = spr_addr;
assign spr_bus_we_o = spr_write_access & spr_group_present & spr_bus_access;
assign spr_bus_we_o = spr_write_authorized & spr_group_present & spr_bus_access;
assign spr_bus_stb_o = (spr_read_access | spr_write_access) &
spr_group_present & spr_bus_access;
assign spr_bus_dat_o = spr_write_dat;
Expand Down
9 changes: 7 additions & 2 deletions rtl/verilog/mor1kx_ctrl_prontoespresso.v
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ module mor1kx_ctrl_prontoespresso
wire spr_group_present;
wire [3:0] spr_group;
wire spr_we;
wire spr_write_authorized;
wire spr_read;
wire [OPTION_OPERAND_WIDTH-1:0] spr_write_dat;
wire [11:0] spr_access_ack;
Expand Down Expand Up @@ -1056,13 +1057,17 @@ module mor1kx_ctrl_prontoespresso
assign spr_read_access = (op_mfspr | (du_access & !du_we_i));
assign spr_write_access = ((execute_done & op_mtspr) | (du_access & du_we_i));

/* Check privilege before allowing an SPR write. */
assign spr_write_authorized = (op_mtspr & spr_sr[`OR1K_SPR_SR_SM]) |
(du_access & du_we_i);

assign spr_write_dat = du_access ? du_dat_i : b;
assign spr_we = spr_write_access & spr_group_present;
assign spr_we = spr_write_authorized & spr_group_present;
assign spr_read = spr_read_access & spr_group_present;

/* A bus out to other units that live outside of the control unit */
assign spr_bus_addr_o = spr_addr;
assign spr_bus_we_o = spr_write_access & spr_group_present & spr_bus_access;
assign spr_bus_we_o = spr_write_authorized & spr_group_present & spr_bus_access;
assign spr_bus_stb_o = (spr_read_access | spr_write_access) &
spr_group_present & spr_bus_access;
assign spr_bus_dat_o = spr_write_dat;
Expand Down