Cvvdev/dev/formating4 (#920)

Several format cleanings:
- split load_store_unit.sv to create lsu_bypass.sv
- add several "begin" and "end"
This commit is contained in:
JeanRochCoulon 2022-06-28 22:15:55 +02:00 committed by GitHub
parent 767c465cfb
commit a9c7b4f1e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 153 additions and 122 deletions

View file

@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv

View file

@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv

View file

@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv

View file

@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv

View file

@ -112,6 +112,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv

View file

@ -1180,10 +1180,11 @@ module csr_regfile import ariane_pkg::*; #(
for(int i = 0; i < 16; i++) begin
if(i < NrPMPEntries) begin
// We only support >=8-byte granularity, NA4 is disabled
if(pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1))
if(pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin
pmpcfg_q[i] <= pmpcfg_d[i];
else
end else begin
pmpcfg_q[i] <= pmpcfg_q[i];
end
pmpaddr_q[i] <= pmpaddr_d[i];
end else begin
pmpcfg_q[i] <= '0;

View file

@ -927,7 +927,7 @@ module cva6 import ariane_pkg::*; #(
//pragma translate_on
`ifdef RVFI_TRACE
always_comb
always_comb begin
for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
logic exception, mem_exception;
exception = commit_instr_id_commit[i].valid && ex_commit.valid;
@ -958,6 +958,7 @@ module cva6 import ariane_pkg::*; #(
rvfi_o[i].rd_wdata = ariane_pkg::is_rd_fpr(commit_instr_id_commit[i].op) == 0 ? wdata_commit_id[i] : commit_instr_id_commit[i].result;
rvfi_o[i].pc_rdata = commit_instr_id_commit[i].pc;
end
end
`endif
endmodule // ariane

View file

@ -129,7 +129,7 @@ module frontend import ariane_pkg::*; #(
// the prediction we saved from the previous fetch
assign bht_prediction_shifted[0] = (serving_unaligned) ? bht_q : bht_prediction[addr[0][1]];
assign btb_prediction_shifted[0] = (serving_unaligned) ? btb_q : btb_prediction[addr[0][1]];
if (ariane_pkg::RVC) begin : gen_btb_prediction_shifted
// for all other predictions we can use the generated address to index
// into the branch prediction data structures
@ -138,7 +138,7 @@ module frontend import ariane_pkg::*; #(
assign btb_prediction_shifted[i] = btb_prediction[addr[i][$clog2(INSTR_PER_FETCH):1]];
end
end;
// for the return address stack it doens't matter as we have the
// address of the call/return already
logic bp_valid;
@ -361,7 +361,9 @@ module frontend import ariane_pkg::*; #(
icache_ex_valid_q <= ariane_pkg::FE_INSTR_PAGE_FAULT;
end else if (icache_dreq_i.ex.cause == riscv::INSTR_ACCESS_FAULT) begin
icache_ex_valid_q <= ariane_pkg::FE_INSTR_ACCESS_FAULT;
end else icache_ex_valid_q <= ariane_pkg::FE_NONE;
end else begin
icache_ex_valid_q <= ariane_pkg::FE_NONE;
end
// save the uppermost prediction
btb_q <= btb_prediction[INSTR_PER_FETCH-1];
bht_q <= bht_prediction[INSTR_PER_FETCH-1];

View file

@ -40,11 +40,12 @@ module id_stage (
input logic tsr_i
);
// ID/ISSUE register stage
struct packed {
typedef struct packed {
logic valid;
ariane_pkg::scoreboard_entry_t sbe;
logic is_ctrl_flow;
} issue_n, issue_q;
} issue_struct_t;
issue_struct_t issue_n, issue_q;
logic is_control_flow_instr;
ariane_pkg::scoreboard_entry_t decoded_instruction;

View file

@ -212,11 +212,12 @@ module issue_read_operands import ariane_pkg::*; #(
operand_b_n = operand_b_regfile;
// immediates are the third operands in the store case
// for FP operations, the imm field can also be the third operand from the regfile
if (NR_RGPR_PORTS == 3)
if (NR_RGPR_PORTS == 3) begin
imm_n = is_imm_fpr(issue_instr_i.op) ? {{riscv::XLEN-FLEN{1'b0}}, operand_c_regfile} :
issue_instr_i.op == OFFLOAD ? operand_c_regfile : issue_instr_i.result;
else
end else begin
imm_n = is_imm_fpr(issue_instr_i.op) ? {{riscv::XLEN-FLEN{1'b0}}, operand_c_regfile} : issue_instr_i.result;
end
trans_id_n = issue_instr_i.trans_id;
fu_n = issue_instr_i.fu;
operator_n = issue_instr_i.op;
@ -276,12 +277,15 @@ module issue_read_operands import ariane_pkg::*; #(
// we do not want to issue this instruction
if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin
case (issue_instr_i.fu)
ALU:
ALU: begin
alu_valid_q <= 1'b1;
CTRL_FLOW:
end
CTRL_FLOW: begin
branch_valid_q <= 1'b1;
MULT:
end
MULT: begin
mult_valid_q <= 1'b1;
end
FPU : begin
fpu_valid_q <= 1'b1;
fpu_fmt_q <= orig_instr.rftype.fmt; // fmt bits from instruction
@ -292,10 +296,12 @@ module issue_read_operands import ariane_pkg::*; #(
fpu_fmt_q <= orig_instr.rvftype.vfmt; // vfmt bits from instruction
fpu_rm_q <= {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction
end
LOAD, STORE:
LOAD, STORE: begin
lsu_valid_q <= 1'b1;
CSR:
end
CSR: begin
csr_valid_q <= 1'b1;
end
default:;
endcase
end
@ -443,7 +449,7 @@ module issue_read_operands import ariane_pkg::*; #(
.raddr_i ( fp_raddr_pack ),
.rdata_o ( fprdata ),
.waddr_i ( waddr_pack ),
.wdata_i ( wdata_pack ),
.wdata_i ( fp_wdata_pack ),
.we_i ( we_fpr_i ),
.*
);

View file

@ -462,107 +462,3 @@ module load_store_unit import ariane_pkg::*; #(
endmodule
// ------------------
// LSU Control
// ------------------
// The LSU consists of two independent block which share a common address translation block.
// The one block is the load unit, the other one is the store unit. They will signal their readiness
// with separate signals. If they are not ready the LSU control should keep the last applied signals stable.
// Furthermore it can be the case that another request for one of the two store units arrives in which case
// the LSU control should sample it and store it for later application to the units. It does so, by storing it in a
// two element FIFO. This is necessary as we only know very late in the cycle whether the load/store will succeed (address check,
// TLB hit mainly). So we better unconditionally allow another request to arrive and store this request in case we need to.
module lsu_bypass import ariane_pkg::*; (
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input lsu_ctrl_t lsu_req_i,
input logic lsu_req_valid_i,
input logic pop_ld_i,
input logic pop_st_i,
output lsu_ctrl_t lsu_ctrl_o,
output logic ready_o
);
lsu_ctrl_t [1:0] mem_n, mem_q;
logic read_pointer_n, read_pointer_q;
logic write_pointer_n, write_pointer_q;
logic [1:0] status_cnt_n, status_cnt_q;
logic empty;
assign empty = (status_cnt_q == 0);
assign ready_o = empty;
always_comb begin
automatic logic [1:0] status_cnt;
automatic logic write_pointer;
automatic logic read_pointer;
status_cnt = status_cnt_q;
write_pointer = write_pointer_q;
read_pointer = read_pointer_q;
mem_n = mem_q;
// we've got a valid LSU request
if (lsu_req_valid_i) begin
mem_n[write_pointer_q] = lsu_req_i;
write_pointer++;
status_cnt++;
end
if (pop_ld_i) begin
// invalidate the result
mem_n[read_pointer_q].valid = 1'b0;
read_pointer++;
status_cnt--;
end
if (pop_st_i) begin
// invalidate the result
mem_n[read_pointer_q].valid = 1'b0;
read_pointer++;
status_cnt--;
end
if (pop_st_i && pop_ld_i)
mem_n = '0;
if (flush_i) begin
status_cnt = '0;
write_pointer = '0;
read_pointer = '0;
mem_n = '0;
end
// default assignments
read_pointer_n = read_pointer;
write_pointer_n = write_pointer;
status_cnt_n = status_cnt;
end
// output assignment
always_comb begin : output_assignments
if (empty) begin
lsu_ctrl_o = lsu_req_i;
end else begin
lsu_ctrl_o = mem_q[read_pointer_q];
end
end
// registers
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
mem_q <= '0;
status_cnt_q <= '0;
write_pointer_q <= '0;
read_pointer_q <= '0;
end else begin
mem_q <= mem_n;
status_cnt_q <= status_cnt_n;
write_pointer_q <= write_pointer_n;
read_pointer_q <= read_pointer_n;
end
end
endmodule

119
core/lsu_bypass.sv Normal file
View file

@ -0,0 +1,119 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Florian Zaruba, ETH Zurich
// Date: 19.04.2017
// Description: Load Store Unit, handles address calculation and memory interface signals
// ------------------
// LSU Control
// ------------------
// The LSU consists of two independent block which share a common address translation block.
// The one block is the load unit, the other one is the store unit. They will signal their readiness
// with separate signals. If they are not ready the LSU control should keep the last applied signals stable.
// Furthermore it can be the case that another request for one of the two store units arrives in which case
// the LSU control should sample it and store it for later application to the units. It does so, by storing it in a
// two element FIFO. This is necessary as we only know very late in the cycle whether the load/store will succeed (address check,
// TLB hit mainly). So we better unconditionally allow another request to arrive and store this request in case we need to.
module lsu_bypass import ariane_pkg::*; (
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input lsu_ctrl_t lsu_req_i,
input logic lsu_req_valid_i,
input logic pop_ld_i,
input logic pop_st_i,
output lsu_ctrl_t lsu_ctrl_o,
output logic ready_o
);
lsu_ctrl_t [1:0] mem_n, mem_q;
logic read_pointer_n, read_pointer_q;
logic write_pointer_n, write_pointer_q;
logic [1:0] status_cnt_n, status_cnt_q;
logic empty;
assign empty = (status_cnt_q == 0);
assign ready_o = empty;
always_comb begin
automatic logic [1:0] status_cnt;
automatic logic write_pointer;
automatic logic read_pointer;
status_cnt = status_cnt_q;
write_pointer = write_pointer_q;
read_pointer = read_pointer_q;
mem_n = mem_q;
// we've got a valid LSU request
if (lsu_req_valid_i) begin
mem_n[write_pointer_q] = lsu_req_i;
write_pointer++;
status_cnt++;
end
if (pop_ld_i) begin
// invalidate the result
mem_n[read_pointer_q].valid = 1'b0;
read_pointer++;
status_cnt--;
end
if (pop_st_i) begin
// invalidate the result
mem_n[read_pointer_q].valid = 1'b0;
read_pointer++;
status_cnt--;
end
if (pop_st_i && pop_ld_i)
mem_n = '0;
if (flush_i) begin
status_cnt = '0;
write_pointer = '0;
read_pointer = '0;
mem_n = '0;
end
// default assignments
read_pointer_n = read_pointer;
write_pointer_n = write_pointer;
status_cnt_n = status_cnt;
end
// output assignment
always_comb begin : output_assignments
if (empty) begin
lsu_ctrl_o = lsu_req_i;
end else begin
lsu_ctrl_o = mem_q[read_pointer_q];
end
end
// registers
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
mem_q <= '0;
status_cnt_q <= '0;
write_pointer_q <= '0;
read_pointer_q <= '0;
end else begin
mem_q <= mem_n;
status_cnt_q <= status_cnt_n;
write_pointer_q <= write_pointer_n;
read_pointer_q <= read_pointer_n;
end
end
endmodule

View file

@ -69,9 +69,9 @@ module re_name import ariane_pkg::*; (
issue_instr_o.rs2 = { ENABLE_RENAME & name_bit_rs2, issue_instr_i.rs2[4:0] };
// re-name the third operand in imm if it's actually an operand
if (is_imm_fpr(issue_instr_i.op))
if (is_imm_fpr(issue_instr_i.op)) begin
issue_instr_o.result = { ENABLE_RENAME & name_bit_rs3, issue_instr_i.result[4:0]};
end
// re-name the destination register
issue_instr_o.rd = { ENABLE_RENAME & name_bit_rd, issue_instr_i.rd[4:0] };