Added initial decoder implementation

This commit is contained in:
Florian Zaruba 2017-04-15 13:26:33 +02:00
parent 5ccee278b7
commit 88b5e1d9ab
6 changed files with 448 additions and 127 deletions

View file

@ -12,7 +12,7 @@ agents = tb/agents/fu_if/fu_if.sv tb/agents/fu_if/fu_if_agent_pkg.sv \
# this list contains the standalone components
src = alu.sv tb/sequences/alu_sequence_pkg.sv tb/env/alu_env_pkg.sv tb/test/alu_lib_pkg.sv tb/alu_tb.sv \
issue_read_operands.sv
issue_read_operands.sv decoder.sv
# Search here for include files (e.g.: non-standalone components)
incdir = ./includes

168
decoder.sv Normal file
View file

@ -0,0 +1,168 @@
import ariane_pkg::*;
module decoder (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic [63:0] pc_i, // PC from IF
input logic [31:0] instruction_i, // instruction from IF
input exception ex_i, // if an exception occured in if
output scoreboard_entry instruction_o, // scoreboard entry to scoreboard
output logic illegal_instr_o
);
instruction instr;
assign instr = instruction'(instruction_i);
imm_sel_t imm_select;
logic [63:0] imm_i_type;
logic [63:0] imm_iz_type;
logic [63:0] imm_s_type;
logic [63:0] imm_sb_type;
logic [63:0] imm_u_type;
logic [63:0] imm_uj_type;
logic [63:0] imm_z_type;
logic [63:0] imm_s2_type;
logic [63:0] imm_bi_type;
logic [63:0] imm_s3_type;
logic [63:0] imm_vs_type;
logic [63:0] imm_vu_type;
always_comb begin : decoder
imm_select = NOIMM;
illegal_instr_o = 1'b0;
instruction_o.valid = 1'b0;
instruction_o.ex = ex_i;
instruction_o.fu = NONE;
instruction_o.op = ADD;
instruction_o.rs1 = 5'b0;
instruction_o.rs2 = 5'b0;
instruction_o.rd = 5'b0;
instruction_o.pc = pc_i;
if (~ex_i.valid) begin
case (instr.rtype.opcode)
OPCODE_SYSTEM: begin
// TODO: Implement
end
OPCODE_FENCE: begin
// TODO: Implement
end
OPCODE_OP: begin
instruction_o.fu = ALU;
instruction_o.rs1 = instr.rtype.rs1;
instruction_o.rs2 = instr.rtype.rs2;
instruction_o.rd = instr.rtype.rd;
unique case ({instr.rtype.funct7, instr.rtype.funct3})
{6'b00_0000, 3'b000}: instruction_o.op = ADD; // Add
{6'b10_0000, 3'b000}: instruction_o.op = SUB; // Sub
{6'b00_0000, 3'b010}: instruction_o.op = SLTS; // Set Lower Than
{6'b00_0000, 3'b011}: instruction_o.op = SLTU; // Set Lower Than Unsigned
{6'b00_0000, 3'b100}: instruction_o.op = XORL; // Xor
{6'b00_0000, 3'b110}: instruction_o.op = ORL; // Or
{6'b00_0000, 3'b111}: instruction_o.op = ANDL; // And
{6'b00_0000, 3'b001}: instruction_o.op = SLL; // Shift Left Logical
{6'b00_0000, 3'b101}: instruction_o.op = SRL; // Shift Right Logical
{6'b10_0000, 3'b101}: instruction_o.op = SRA; // Shift Right Arithmetic
default: begin
illegal_instr_o = 1'b1;
end
endcase
end
OPCODE_OP32: begin
end
OPCODE_OPIMM: begin
imm_select = IIMM;
end
OPCODE_OPIMM32: begin
imm_select = IIMM;
end
OPCODE_STORE: begin
imm_select = SIMM;
end
OPCODE_LOAD: begin
imm_select = IIMM;
end
OPCODE_BRANCH: begin
imm_select = BIMM;
end
OPCODE_JALR: begin
imm_select = UIMM;
end
OPCODE_JAL: begin
imm_select = JIMM;
end
OPCODE_AUIPC: begin
imm_select = UIMM;
end
OPCODE_LUI: begin
imm_select = UIMM;
end
default: illegal_instr_o = 1'b1;
endcase
end
end
always_comb begin : sign_extend
imm_i_type = { {52 {instruction_i[31]}}, instruction_i[31:20] };
imm_iz_type = { 52'b0, instruction_i[31:20] };
imm_s_type = { {52 {instruction_i[31]}}, instruction_i[31:25], instruction_i[11:7] };
imm_sb_type = { {51 {instruction_i[31]}}, instruction_i[31], instruction_i[7], instruction_i[30:25], instruction_i[11:8], 1'b0 };
imm_u_type = { {32 {instruction_i[31]}}, instruction_i[31:12], 12'b0 }; // JAL, AUIPC, sign extended to 64 bit
imm_uj_type = { {44 {instruction_i[31]}}, instruction_i[19:12], instruction_i[20], instruction_i[30:21], 1'b0 };
// imm_z_type = { 59'b0, instruction_i[`REG_S1] };
imm_s2_type = { 59'b0, instruction_i[24:20] };
imm_bi_type = { {59{instruction_i[24]}}, instruction_i[24:20] };
imm_s3_type = { 59'b0, instruction_i[29:25] };
imm_vs_type = { {58 {instruction_i[24]}}, instruction_i[24:20], instruction_i[25] };
imm_vu_type = { 58'b0, instruction_i[24:20], instruction_i[25] };
// NOIMM, PCIMM, IIMM, SIMM, BIMM, BIMM, UIMM, JIMM
// select immediate
case (imm_select)
PCIMM: begin
instruction_o.imm = pc_i;
instruction_o.use_imm = 1'b1;
end
IIMM: begin
instruction_o.imm = imm_i_type;
instruction_o.use_imm = 1'b1;
end
SIMM: begin
instruction_o.imm = imm_s_type;
instruction_o.use_imm = 1'b1;
end
BIMM: begin
instruction_o.imm = imm_bi_type;
instruction_o.use_imm = 1'b1;
end
UIMM: begin
instruction_o.imm = imm_u_type;
instruction_o.use_imm = 1'b1;
end
JIMM: begin
instruction_o.imm = imm_uj_type;
instruction_o.use_imm = 1'b1;
end
default: begin
instruction_o.imm = 64'b0;
instruction_o.use_imm = 1'b0;
end
endcase
end
endmodule

View file

@ -10,70 +10,137 @@
*/
package ariane_pkg;
// ---------------
// Fetch Stage
// ---------------
// ---------------
// Fetch Stage
// ---------------
// Only use struct when signals have same direction
typedef struct packed {
logic [63:0] pc;
logic [63:0] branch_target_address;
logic valid;
} btb;
// Only use struct when signals have same direction
typedef struct packed {
logic [63:0] pc;
logic [63:0] branch_target_address;
logic valid;
} btb;
// input to the fetch stage
typedef struct packed {
logic [63:0] ra; // return address
logic is_call; // is call - pop from stack
logic is_return; // is return - push on stack
} ras;
// input to the fetch stage
typedef struct packed {
logic [63:0] ra; // return address
logic is_call; // is call - pop from stack
logic is_return; // is return - push on stack
} ras;
// exception
typedef struct packed {
logic [63:0] epc;
logic [63:0] cause;
logic valid;
} exception;
// exception
typedef struct packed {
logic [63:0] epc;
logic [63:0] cause;
logic valid;
} exception;
// miss-predict
typedef struct packed {
logic [63:0] pc;
logic valid; // is miss-predict
} misspredict;
// miss-predict
typedef struct packed {
logic [63:0] pc;
logic valid; // is miss-predict
} misspredict;
typedef enum logic[3:0] {
NONE, ALU, MULT, LSU, CSR
} fu_t;
typedef enum logic[3:0] {
NONE, ALU, MULT, LSU, CSR
} fu_t;
// ---------------
// EX Stage
// ---------------
// ---------------
// EX Stage
// ---------------
typedef enum logic [7:0] { ADD, SUB, ADDW, SUBW, // basic ALU op
XORL, ORL, ANDL, // logic operations
SRA, SRL, SLL, SRLW, SLLW, SRAW, // shifts
LTS, LTU, LES, LEU, GTS, GTU, GES, GEU, EQ, NE, // comparisons
SLTS, SLTU, SLETS, SLETU, // set lower than operations
MRET, SRET, URET, ECALL, WRITE, READ, SET, CLEAR, // CSR functions
LD, SD, LW, SW, LH, SH, LB, SB, LBU, SBU // LSU functions
} alu_op;
typedef enum logic [7:0] { ADD, SUB, ADDW, SUBW, // basic ALU op
XORL, ORL, ANDL, // logic operations
SRA, SRL, SLL, SRLW, SLLW, SRAW, // shifts
LTS, LTU, LES, LEU, GTS, GTU, GES, GEU, EQ, NE, // comparisons
SLTS, SLTU, SLETS, SLETU, // set lower than operations
MRET, SRET, URET, ECALL, WRITE, READ, SET, CLEAR, // CSR functions
LD, SD, LW, SW, LH, SH, LB, SB, LBU, SBU // LSU functions
} alu_op;
// ---------------
// ID/EX/WB Stage
// ---------------
typedef struct packed {
logic [63:0] pc;
fu_t fu;
alu_op op;
logic [4:0] rs1;
logic [4:0] rs2;
logic [4:0] rd;
logic [63:0] result;
logic valid;
logic use_imm;
logic [63:0] imm; // maybe we can get this into the results field
exception ex; // the PC is redundant here
} scoreboard_entry;
// --------------------
// Instruction Types
// --------------------
typedef struct packed {
logic [6:0] opcode;
logic [11:7] rd;
logic [14:12] funct3;
logic [19:15] rs1;
logic [24:20] rs2;
logic [31:25] funct7;
} rtype;
typedef struct packed {
logic [6:0] opcode;
logic [11:7] rd;
logic [14:12] funct3;
logic [19:15] rs1;
logic [31:20] imm;
} itype;
typedef struct packed {
logic [6:0] opcode;
logic [11:7] imm0;
logic [14:12] funct3;
logic [19:15] rs1;
logic [24:20] rs2;
logic [31:25] imm1;
} stype;
typedef struct packed {
logic [6:0] opcode;
logic [11:7] rd;
logic [31:12] funct3;
} utype;
typedef union packed {
logic [31:0] instr;
rtype rtype;
itype itype;
stype stype;
utype utype;
} instruction;
// --------------------
// Opcodes
// --------------------
localparam OPCODE_SYSTEM = 7'h73;
localparam OPCODE_FENCE = 7'h0f;
localparam OPCODE_OP = 7'h33;
localparam OPCODE_OP32 = 7'h3B;
localparam OPCODE_OPIMM = 7'h13;
localparam OPCODE_OPIMM32 = 7'h1B;
localparam OPCODE_STORE = 7'h23;
localparam OPCODE_LOAD = 7'h03;
localparam OPCODE_BRANCH = 7'h63;
localparam OPCODE_JALR = 7'h67;
localparam OPCODE_JAL = 7'h6f;
localparam OPCODE_AUIPC = 7'h17;
localparam OPCODE_LUI = 7'h37;
// --------------------
// Immediate select
// --------------------
typedef enum logic[3:0] {
NOIMM, PCIMM, IIMM, SIMM, BIMM, UIMM, JIMM
} imm_sel_t;
// ---------------
// ID/EX/WB Stage
// ---------------
typedef struct packed {
logic [63:0] pc;
fu_t fu;
alu_op op;
logic [4:0] rs1;
logic [4:0] rs2;
logic [4:0] rd;
logic [63:0] result;
logic valid;
logic use_imm;
logic [63:0] imm; // maybe we can get this into the results field
exception ex; // the PC is redundant here
} scoreboard_entry;
endpackage

View file

@ -51,10 +51,20 @@ module issue_read_operands (
);
logic stall; // stall signal, we do not want to fetch any more entries
logic fu_busy; // functional unit is busy
scoreboard_entry sbe_n, sbe_q; // instruction register (ID <-> EX)
logic [63:0] operand_a_regfile_n, operand_a_regfile_q, operand_b_regfile_n, operand_b_regfile_q; // operands coming from regfile
logic [63:0] operand_a_regfile, operand_b_regfile; // operands coming from regfile
// output flipflop (ID <-> EX)
logic [63:0] operand_a_n, operand_a_q, operand_b_n, operand_b_q;
logic alu_valid_n, alu_valid_q;
alu_op operator_n, operator_q;
// forwarding signals
logic forward_rs1, forward_rs2;
assign operand_a_o = operand_a_q;
assign operand_b_o = operand_b_q;
assign operator_o = operator_q;
assign alu_valid_o = alu_valid_q;
// ---------------
// Issue Stage
// ---------------
@ -63,7 +73,6 @@ module issue_read_operands (
// We also need to check if there is an unresolved branch in the scoreboard.
always_comb begin : issue
// default assignment
sbe_n = sbe_q;
issue_ack_o = 1'b0;
// check that we didn't stall, that the instruction we got is valid
// and that the functional unit we need is not busy
@ -71,7 +80,6 @@ module issue_read_operands (
// check that the corresponding functional unit is not busy
// no other instruction has the same destination register -> fetch the instruction
if (rd_clobber_i[issue_instr_i.rd] == NONE) begin
sbe_n = issue_instr_i;
issue_ack_o = 1'b1;
end
end
@ -98,7 +106,6 @@ module issue_read_operands (
// ---------------
// Register stage
// ---------------
assign operator_o = sbe_q.op;
// check that all operands are available, otherwise stall
// forward corresponding register
always_comb begin : operands_available
@ -106,12 +113,12 @@ module issue_read_operands (
// operand forwarding signals
forward_rs1 = 1'b0;
forward_rs2 = 1'b0;
// address needs to be applied one cycle earlier
// poll the scoreboard for those values
rs1_o = issue_instr_i.rs1;
rs2_o = issue_instr_i.rs2;
// 1. check if the source registers are clobberd
// 2. poll the scoreboard
if (rd_clobber_i[sbe_q.rs1] != NONE) begin
if (rd_clobber_i[issue_instr_i.rs1] != NONE) begin
// the operand is available, forward it
if (rs1_valid_i)
forward_rs1 = 1'b1;
@ -120,7 +127,7 @@ module issue_read_operands (
end
if (rd_clobber_i[sbe_q.rs2] != NONE) begin
if (rd_clobber_i[issue_instr_i.rs2] != NONE) begin
// the operand is available, forward it
if (rs2_valid_i)
forward_rs2 = 1'b1;
@ -133,35 +140,35 @@ module issue_read_operands (
// Forwarding/Output MUX
always_comb begin : forwarding
// default is regfile
operand_a_o = operand_a_regfile_q;
operand_b_o = operand_b_regfile_q;
operand_a_n = operand_a_regfile;
operand_b_n = operand_b_regfile;
// or should we forward
if (forward_rs1) begin
operand_a_o = rs1_i;
operand_a_n = rs1_i;
end
if (forward_rs2) begin
operand_b_o = rs2_i;
operand_b_n = rs2_i;
end
// or is it an immediate (including PC)
if (sbe_q.use_imm) begin
operand_b_o = sbe_q.imm;
if (issue_instr_i.use_imm) begin
operand_b_n = issue_instr_i.imm;
end
end
// FU select
always_comb begin : unit_valid
alu_valid_o = 1'b0;
alu_valid_n = alu_valid_q;
lsu_valid_o = 1'b0;
mult_valid_o = 1'b0;
// Exception pass through
// if an exception has occurred simply pass it through
if (~sbe_q.ex.valid) begin
case (sbe_q.fu)
if (~issue_instr_i.ex.valid) begin
case (issue_instr_i.fu)
ALU:
alu_valid_o = 1'b1;
alu_valid_n = 1'b1;
MULT:
mult_valid_o = 1'b1;
LSU:
@ -183,10 +190,10 @@ module issue_read_operands (
.test_en_i ( test_en_i ),
.raddr_a_i ( issue_instr_i.rs1 ),
.rdata_a_o ( operand_a_regfile_n ),
.rdata_a_o ( operand_a_regfile ),
.raddr_b_i ( issue_instr_i.rs2 ),
.rdata_b_o ( operand_b_regfile_n ),
.rdata_b_o ( operand_b_regfile ),
.waddr_a_i ( waddr_a_i ),
.wdata_a_i ( wdata_a_i ),
@ -196,13 +203,15 @@ module issue_read_operands (
// Registers
always_ff @(posedge clk_i or negedge rst_ni) begin
if(~rst_ni) begin
sbe_q <= '{default: 0};
operand_a_regfile_q <= '{default: 0};
operand_b_regfile_q <= '{default: 0};
operand_a_q <= '{default: 0};
operand_b_q <= '{default: 0};
alu_valid_q <= 1'b0;
operator_q <= ADD;
end else begin
sbe_q <= sbe_n;
operand_a_regfile_q <= operand_a_regfile_n;
operand_b_regfile_q <= operand_b_regfile_n;
operand_a_q <= operand_a_n;
operand_b_q <= operand_b_n;
alu_valid_q <= alu_valid_n;
operator_q <= operator_n;
end
end
endmodule

100
regfile_ff.sv Executable file
View file

@ -0,0 +1,100 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017 ETH Zurich, University of Bologna //
// All rights reserved. //
// //
// This code is under development and not yet released to the public. //
// Until it is released, the code is under the copyright of ETH Zurich //
// and the University of Bologna, and may contain unpublished work. //
// Any reuse/redistribution should only be under explicit permission. //
// //
// Bug fixes and contributions will eventually be released under the //
// SolderPad open hardware license and under the copyright of ETH Zurich //
// and the University of Bologna. //
// //
// Engineer: Francesco Conti - f.conti@unibo.it //
// //
// Additional contributions by: //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V register file //
// Project Name: zero-riscy //
// Language: SystemVerilog //
// //
// Description: Register file with 31 or 15x 32 bit wide registers. //
// Register 0 is fixed to 0. This register file is based on //
// flip flops. //
// //
////////////////////////////////////////////////////////////////////////////////
module regfile
#(
parameter DATA_WIDTH = 32
)
(
// Clock and Reset
input logic clk,
input logic rst_n,
input logic test_en_i,
//Read port R1
input logic [4:0] raddr_a_i,
output logic [DATA_WIDTH-1:0] rdata_a_o,
//Read port R2
input logic [4:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// Write port W1
input logic [4:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i
);
localparam ADDR_WIDTH = 5;
localparam NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg;
logic [NUM_WORDS-1:0] we_a_dec;
always_comb
begin : we_a_decoder
for (int i = 0; i < NUM_WORDS; i++) begin
if (waddr_a_i == i)
we_a_dec[i] = we_a_i;
else
we_a_dec[i] = 1'b0;
end
end
genvar i;
generate
// loop from 1 to NUM_WORDS-1 as R0 is nil
for (i = 1; i < NUM_WORDS; i++)
begin : rf_gen
always_ff @(posedge clk, negedge rst_n)
begin : register_write_behavioral
if (rst_n==1'b0) begin
rf_reg[i] <= 'b0;
end else begin
if (we_a_dec[i])
rf_reg[i] <= wdata_a_i;
end
end
end
// R0 is nil
assign rf_reg[0] = '0;
endgenerate
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
endmodule

View file

@ -54,11 +54,7 @@ dtype [NR_ENTRIES-1:0] mem_q, mem_n;
logic [BITS_ENTRIES-1:0] issue_pointer_n, issue_pointer_q, // points to the instruction currently in issue
commit_pointer_n, commit_pointer_q, // points to the instruction currently in commit
top_pointer_n, top_pointer_q, top_pointer_qq; // points to the top of the scoreboard, an empty slot, top pointer two cycles ago
// rd clobber register
logic [31:0][$bits(fu_t)-1:0] rd_clobber_n, rd_clobber_q;
// register read stage
logic [63:0] rs1_n, rs1_q, rs2_n, rs2_q;
logic rs1_valid_n, rs1_valid_q, rs2_valid_n, rs2_valid_q;
logic pointer_overflow;
logic empty;
logic reset_condition;
@ -69,11 +65,7 @@ assign reset_condition = top_pointer_q == top_pointer_qq;
assign pointer_overflow = (top_pointer_q <= commit_pointer_q && ~reset_condition) ? 1'b1 : 1'b0;
assign full_o = (reset_condition) ? 1'b0 : (commit_pointer_q == top_pointer_q);
assign empty = (pointer_overflow) ? 1'b0 : (commit_pointer_q == top_pointer_q);
assign rd_clobber_o = rd_clobber_q;
assign rs1_o = rs1_q;
assign rs2_o = rs2_q;
assign rs1_valid_o = rs1_valid_q;
assign rs2_valid_o = rs2_valid_q;
// rd_clobber output: output currently clobbered destination registers
// but only between commit and issue pointer
// normal case: overflow case:
@ -85,31 +77,31 @@ assign rs2_valid_o = rs2_valid_q;
// |_________________________|<- top pointer |_________________________|
//
always_comb begin : clobber_output
rd_clobber_n = rd_clobber_q;
rd_clobber_o = '{default: 0};
// excluding issue, the issue pointer points to the instruction which is currently not issued
// but might be issued as soon as the issue unit acknowledges
if (commit_pointer_q < issue_pointer_q) begin
for (int unsigned i = 0; i < NR_ENTRIES; i++) begin
// non overflowed case, depicted on the left
if (i[BITS_ENTRIES-1:0] >= commit_pointer_q && i[BITS_ENTRIES-1:0] < issue_pointer_q)
rd_clobber_n[mem_q[i].rd] = mem_q[i].fu;
rd_clobber_o[mem_q[i].rd] = mem_q[i].fu;
end
end else begin // the issue pointer has overflowed, invert logic, depicted on the right
for (int unsigned i = 0; i < NR_ENTRIES; i++) begin
if (i[BITS_ENTRIES-1:0] >= commit_pointer_q || i[BITS_ENTRIES-1:0] < issue_pointer_q)
rd_clobber_n[mem_q[i].rd] = mem_q[i].fu;
rd_clobber_o[mem_q[i].rd] = mem_q[i].fu;
end
end
// // the zero register is always free
rd_clobber_n[0] = NONE;
// the zero register is always free
rd_clobber_o[0] = NONE;
end
// read operand interface: same logic as register file, including a valid file
always_comb begin : read_operands
rs1_n = rs1_q;
rs2_n = rs2_q;
rs1_valid_n = rs1_valid_q;
rs2_valid_n = rs2_valid_q;
rs1_o = 64'b0;
rs2_o = 64'b0;
rs1_valid_o = 1'b0;
rs2_valid_o = 1'b0;
if (commit_pointer_q < issue_pointer_q) begin
for (int unsigned i = 0; i < NR_ENTRIES; i++) begin
@ -117,12 +109,12 @@ always_comb begin : read_operands
// look at the appropriate fields and look whether there was an
// instruction that wrote the rd field before, first for RS1 and then for RS2
if (mem_q[i[BITS_ENTRIES-1:0]].rd == rs1_i) begin
rs1_n = mem_q[i].result;
rs1_valid_n = mem_q[i].valid;
rs1_o = mem_q[i].result;
rs1_valid_o = mem_q[i].valid;
// do the same for rs2
end else if (mem_q[i].rd == rs2_i) begin
rs2_n = mem_q[i].result;
rs2_valid_n = mem_q[i].valid;
rs2_o = mem_q[i].result;
rs2_valid_o = mem_q[i].valid;
end
end
end
@ -131,21 +123,21 @@ always_comb begin : read_operands
if (i[BITS_ENTRIES-1:0] >= commit_pointer_q || i[BITS_ENTRIES-1:0] < issue_pointer_q) begin
// same as above but for the overflowed pointer case
if (mem_q[i[BITS_ENTRIES-1:0]].rd == rs1_i) begin
rs1_n = mem_q[i].result;
rs1_valid_n = mem_q[i].valid;
rs1_o = mem_q[i].result;
rs1_valid_o = mem_q[i].valid;
// do the same for rs2
end else if (mem_q[i[BITS_ENTRIES-1:0]].rd == rs2_i) begin
rs2_n = mem_q[i].result;
rs2_valid_n = mem_q[i].valid;
rs2_o = mem_q[i].result;
rs2_valid_o = mem_q[i].valid;
end
end
end
end
// make sure we didn't read the zero register
if (rs1_i == '0)
rs1_valid_n = 1'b0;
rs1_valid_o = 1'b0;
if (rs2_i == '0)
rs2_valid_n = 1'b0;
rs2_valid_o = 1'b0;
end
// push new decoded instruction: if still empty space push the instruction to the scoreboard
// write-back instruction: update value of RD register in scoreboard
@ -230,33 +222,18 @@ end
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin : sequential
if(~rst_ni) begin
rd_clobber_q <= '{default: 0};
rs1_q <= 64'b0;
rs2_q <= 64'b0;
rs1_valid_q <= 1'b0;
rs2_valid_q <= 1'b0;
issue_pointer_q <= '{default: 0};
commit_pointer_q <= '{default: 0};
top_pointer_q <= '{default: 0};
top_pointer_qq <= '{default: 0};
mem_q <= '{default: 0};
end else if (flush_i) begin // reset pointers on flush
rd_clobber_q <= '{default: 0};
rs1_q <= 64'b0;
rs2_q <= 64'b0;
rs1_valid_q <= 1'b0;
rs2_valid_q <= 1'b0;
issue_pointer_q <= '{default: 0};
commit_pointer_q <= '{default: 0};
top_pointer_q <= '{default: 0};
top_pointer_qq <= '{default: 0};
mem_q <= '{default: 0};
end else begin
rs1_q <= rs1_n;
rs2_q <= rs2_n;
rs1_valid_q <= rs1_valid_n;
rs2_valid_q <= rs2_valid_n;
rd_clobber_q <= rd_clobber_n;
issue_pointer_q <= issue_pointer_n;
commit_pointer_q <= commit_pointer_n;
top_pointer_q <= top_pointer_n;