mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
* Переработка лабораторных работ, связанных с памятью Существенно переработаны ЛР3 и ЛР7: Из ЛР3 убрано задание реализовать память данных. Эта память использовалась только студентами ИВТ и только в рамках одной лабы. В итоге использовалась готовая память, и ничего не мешает использовать ее с самого начала. Задание по реализации памяти инструкций также претерпело изменения. Теперь код памяти инструкций предоставляется сразу. Это объясняется тем, что код модуля состоит в общем-то из 4х строк, на которые тратится слишком много времени (с учетом добавления тестбенча и проверок). Кроме того, использование готового кода позволяет дать модуль чуть посложнее (с параметризацией размера). По итогу правок, третья лабораторная работа превращается чисто в лабораторную по написанию регистрового файла, что должно положительно сказаться на кривой сложности лаб. После второй лабы происходит слишком резкий скачок в объемах работы. Соответственно, в связи с тем, что память данных больше не делается на третьей лабе, дополнительная ЛР по памяти данных с byte enable необходимо перенести до реализации тракта данных. * ЛР3, 5, 6. Правки из ревью * ЛР7. Добавление иллюстраций
1547 lines
58 KiB
Systemverilog
1547 lines
58 KiB
Systemverilog
/* -----------------------------------------------------------------------------
|
|
* Project Name : Architectures of Processor Systems (APS) lab work
|
|
* Organization : National Research University of Electronic Technology (MIET)
|
|
* Department : Institute of Microdevices and Control Systems
|
|
* Author(s) : Andrei Solodovnikov
|
|
* Email(s) : hepoh@org.miet.ru
|
|
|
|
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
|
* ------------------------------------------------------------------------------
|
|
*/
|
|
|
|
module tb_decoder_riscv();
|
|
|
|
import decoder_pkg::*;
|
|
typedef class riscv_instr;
|
|
riscv_instr instr = new();
|
|
|
|
logic clk, test_has_been_finished;
|
|
logic [31:0] fetched_instr_i = '0;
|
|
|
|
int err_count;
|
|
|
|
//list of all valid opcodes
|
|
logic [4:0] opcode_array[11] = {
|
|
LOAD_OPCODE,
|
|
MISC_MEM_OPCODE,
|
|
OP_IMM_OPCODE,
|
|
AUIPC_OPCODE,
|
|
STORE_OPCODE,
|
|
OP_OPCODE,
|
|
LUI_OPCODE,
|
|
BRANCH_OPCODE,
|
|
JALR_OPCODE,
|
|
JAL_OPCODE,
|
|
SYSTEM_OPCODE
|
|
};
|
|
|
|
/*
|
|
Since randomize with overconstraining slows down simulation, it has been
|
|
decided to make a list of all codes instead of looping over every possible
|
|
combination func3 and func7.
|
|
*/
|
|
logic [14:0] valid_codes[44] = {
|
|
{LOAD_OPCODE , 3'h0, 7'h00},
|
|
{LOAD_OPCODE , 3'h1, 7'h00},
|
|
{LOAD_OPCODE , 3'h2, 7'h00},
|
|
{LOAD_OPCODE , 3'h4, 7'h00},
|
|
{LOAD_OPCODE , 3'h5, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h0, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h0, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h1, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h2, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h3, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h4, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h5, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h5, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h6, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h7, 7'h00},
|
|
{AUIPC_OPCODE , 3'h0, 7'h00},
|
|
{STORE_OPCODE , 3'h0, 7'h00},
|
|
{STORE_OPCODE , 3'h1, 7'h00},
|
|
{STORE_OPCODE , 3'h2, 7'h00},
|
|
{OP_OPCODE , 3'h0, 7'h00},
|
|
{OP_OPCODE , 3'h0, 7'h20},
|
|
{OP_OPCODE , 3'h1, 7'h00},
|
|
{OP_OPCODE , 3'h2, 7'h00},
|
|
{OP_OPCODE , 3'h3, 7'h00},
|
|
{OP_OPCODE , 3'h4, 7'h00},
|
|
{OP_OPCODE , 3'h5, 7'h00},
|
|
{OP_OPCODE , 3'h5, 7'h20},
|
|
{OP_OPCODE , 3'h6, 7'h00},
|
|
{OP_OPCODE , 3'h7, 7'h00},
|
|
{LUI_OPCODE , 3'h0, 7'h00},
|
|
{BRANCH_OPCODE , 3'h0, 7'h00},
|
|
{BRANCH_OPCODE , 3'h1, 7'h00},
|
|
{BRANCH_OPCODE , 3'h4, 7'h00},
|
|
{BRANCH_OPCODE , 3'h5, 7'h00},
|
|
{BRANCH_OPCODE , 3'h6, 7'h00},
|
|
{BRANCH_OPCODE , 3'h7, 7'h00},
|
|
{JALR_OPCODE , 3'h0, 7'h00},
|
|
{JAL_OPCODE , 3'h0, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h1, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h2, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h3, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h5, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h6, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h7, 7'h00}
|
|
};
|
|
|
|
logic [14:0] invalid_codes[38] = {
|
|
{LOAD_OPCODE , 3'h3, 7'h00},
|
|
{LOAD_OPCODE , 3'h6, 7'h00},
|
|
{LOAD_OPCODE , 3'h7, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h1, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h2, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h3, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h4, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h5, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h6, 7'h00},
|
|
{MISC_MEM_OPCODE, 3'h7, 7'h00},
|
|
{OP_IMM_OPCODE , 3'h0, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h1, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h2, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h3, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h4, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h6, 7'h20},
|
|
{OP_IMM_OPCODE , 3'h7, 7'h20},
|
|
{STORE_OPCODE , 3'h3, 7'h00},
|
|
{STORE_OPCODE , 3'h4, 7'h00},
|
|
{STORE_OPCODE , 3'h5, 7'h00},
|
|
{STORE_OPCODE , 3'h6, 7'h00},
|
|
{STORE_OPCODE , 3'h7, 7'h00},
|
|
{OP_OPCODE , 3'h1, 7'h20},
|
|
{OP_OPCODE , 3'h2, 7'h20},
|
|
{OP_OPCODE , 3'h3, 7'h20},
|
|
{OP_OPCODE , 3'h4, 7'h20},
|
|
{OP_OPCODE , 3'h6, 7'h20},
|
|
{OP_OPCODE , 3'h7, 7'h20},
|
|
{BRANCH_OPCODE , 3'h2, 7'h00},
|
|
{BRANCH_OPCODE , 3'h3, 7'h00},
|
|
{JALR_OPCODE , 3'h1, 7'h00},
|
|
{JALR_OPCODE , 3'h2, 7'h00},
|
|
{JALR_OPCODE , 3'h3, 7'h00},
|
|
{JALR_OPCODE , 3'h4, 7'h00},
|
|
{JALR_OPCODE , 3'h5, 7'h00},
|
|
{JALR_OPCODE , 3'h6, 7'h00},
|
|
{JALR_OPCODE , 3'h7, 7'h00},
|
|
{SYSTEM_OPCODE , 3'h4, 7'h00}
|
|
};
|
|
|
|
initial begin
|
|
$display("Test has been started");
|
|
$display( "\n\n==========================\nCLICK THE BUTTON 'Run All'\n==========================\n"); $stop();
|
|
|
|
valid_instrs_direct_test();
|
|
valid_instrs_random_test();
|
|
illegal_instr_direct_test();
|
|
illegal_instrs_random_test();
|
|
|
|
$display("\nTest has been finished\nNumber of errors: %d\n", err_count);
|
|
test_has_been_finished = 1'b1;
|
|
$finish();
|
|
end
|
|
|
|
function void randomize_with_given_opcode(input logic[4:0] given_opcode);
|
|
if(!instr.randomize() with {(opcode == given_opcode);}) begin
|
|
$fatal(1, "Can't ranomize instr with opcode == %0h", given_opcode);
|
|
end
|
|
endfunction
|
|
|
|
task valid_instrs_direct_test();
|
|
/*
|
|
Enumeration of all possible instructions by every opcode, func3 and func7.
|
|
Additionally, ecall, ebreak and mret instructions are generated manually.
|
|
*/
|
|
foreach(valid_codes[i]) begin
|
|
if(instr.randomize() with {(opcode == valid_codes[i][14:10]) && (func3 == valid_codes[i][9:7]) && (func7 == valid_codes[i][6:0]);}) begin
|
|
@(posedge clk);
|
|
fetched_instr_i <= instr.bits;
|
|
end
|
|
else begin
|
|
$fatal(1, "Can't randomize instruction with opcode == %02h, func3 == %0h, func7 == %0h", valid_codes[i][14:10], valid_codes[i][9:7], valid_codes[i][6:0]);
|
|
end
|
|
end
|
|
for(int i = 0; i < 3; i++) begin
|
|
@(posedge clk);
|
|
fetched_instr_i <= instr.system_instrs[i];
|
|
end
|
|
endtask
|
|
|
|
task valid_instrs_random_test();
|
|
/*
|
|
A thousand random instructions for each opcode.
|
|
*/
|
|
foreach(opcode_array[i]) begin
|
|
repeat(1e3) begin
|
|
randomize_with_given_opcode(opcode_array[i]);
|
|
@(posedge clk);
|
|
fetched_instr_i <= instr.bits;
|
|
end
|
|
end
|
|
endtask
|
|
|
|
task illegal_instr_direct_test();
|
|
/*
|
|
That's where real things are happening.
|
|
This task is intent to check all the ways to get illegal_instr_o goes 1.
|
|
Test trying:
|
|
- incorrect low 2 bits on every opcode;
|
|
- incorrect opcode;
|
|
- incorrect func3 and func7 where it's possible;
|
|
- incorrect fence, ecall, ebreak, mret instructions
|
|
*/
|
|
incorrect_low_two_bits_test();
|
|
incorrect_opcode_test();
|
|
incorrect_func3_func7_test();
|
|
incorrect_hardcode_instrs();
|
|
endtask
|
|
|
|
task incorrect_low_two_bits_test();
|
|
/*
|
|
For every opcode we generate a valid instruction and corrupt 2 low bits.
|
|
So for every opcode we try 3 different instructions.
|
|
*/
|
|
foreach(opcode_array[i]) begin
|
|
for(int j = 0; j < 3; j++) begin
|
|
randomize_with_given_opcode(opcode_array[i]);
|
|
@(posedge clk);
|
|
fetched_instr_i <= {instr.bits[31:2], j};
|
|
end
|
|
end
|
|
endtask
|
|
|
|
task incorrect_opcode_test();
|
|
/*
|
|
For every instruction type (every opcode for the simplicity sake) we try
|
|
an instruction with incorrect opcode.
|
|
*/
|
|
foreach(opcode_array[i]) begin
|
|
automatic logic [4:0] incorrect_opcode;
|
|
for(int j = 0; j < 3; j++) begin
|
|
randomize_with_given_opcode(opcode_array[i]);
|
|
@(posedge clk);
|
|
assert(std::randomize(incorrect_opcode) with {!(incorrect_opcode inside {
|
|
LOAD_OPCODE,
|
|
MISC_MEM_OPCODE,
|
|
OP_IMM_OPCODE,
|
|
AUIPC_OPCODE,
|
|
STORE_OPCODE,
|
|
OP_OPCODE,
|
|
LUI_OPCODE,
|
|
BRANCH_OPCODE,
|
|
JALR_OPCODE,
|
|
JAL_OPCODE,
|
|
SYSTEM_OPCODE
|
|
});});
|
|
fetched_instr_i <= {instr.bits[31:7], incorrect_opcode, 2'b11};
|
|
end
|
|
end
|
|
endtask
|
|
|
|
task incorrect_func3_func7_test();
|
|
/*
|
|
This test is opposite of valid_instrs_direct_test: we are looping through
|
|
every illegal {opcode, func3, func7} combination and applying it onto
|
|
generated instruction.
|
|
*/
|
|
foreach(invalid_codes[i]) begin
|
|
randomize_with_given_opcode(invalid_codes[i][14:10]);
|
|
@(posedge clk);
|
|
fetched_instr_i <= {invalid_codes[i][6:0], instr.bits[24:15], invalid_codes[i][9:7], instr.bits[11:7], invalid_codes[i][14:10], 2'b11};
|
|
end
|
|
endtask
|
|
|
|
task incorrect_hardcode_instrs();
|
|
/*
|
|
In this test we try to broke fence, ecall, ebreak and mret instructions:
|
|
- for the fence instr we need to make func3 to be not equal zero;
|
|
- for ecall, ebreak and mret instructions we need to corrupt imm, rs1, rd
|
|
values.
|
|
*/
|
|
|
|
// Broken fence instructions
|
|
for(int i = 1; i < 8; i++) begin
|
|
randomize_with_given_opcode(MISC_MEM_OPCODE);
|
|
@(posedge clk);
|
|
fetched_instr_i <= {instr.bits[31:15], i, instr.bits[11:0]};
|
|
end
|
|
|
|
// Broken ecall, ebreak, mret instructions
|
|
for(int j = 0; j < 3; j++) begin
|
|
@(posedge clk);
|
|
// broken imm field
|
|
fetched_instr_i <= {12'd2, instr.system_instrs[j][19:0]};
|
|
@(posedge clk);
|
|
// broken rs1 field
|
|
fetched_instr_i <= {instr.system_instrs[j][31:20], 5'd1, instr.system_instrs[j][14:0]};
|
|
@(posedge clk);
|
|
// broken rd field
|
|
fetched_instr_i <= {instr.system_instrs[j][31:12], 5'd1, instr.system_instrs[j][6:0]};
|
|
end
|
|
endtask
|
|
|
|
task illegal_instrs_random_test();
|
|
/*
|
|
It's inefficiently to randomize all 32 bits of instructions since most
|
|
of them would be illegal by opcode or low 2 bits.
|
|
This test will construct instructions from valid parts but in random order
|
|
which will cause illegal instructions to be produced.
|
|
Additionally test will insert illegal parts with low chance.
|
|
*/
|
|
automatic logic [2:0] func3;
|
|
automatic logic [6:0] func7;
|
|
automatic logic [4:0] opcode;
|
|
automatic logic [4:0] rs1, rs2, rd;
|
|
automatic logic [1:0] low_bits;
|
|
automatic logic [9:0] mutation;
|
|
repeat(1e4) begin
|
|
assert(std::randomize(mutation));
|
|
// we want to broke (invert constraint of) func3 if
|
|
// 9's bit is 1 while six lower bits are 0
|
|
if(mutation[9] & !(|mutation[5:0])) begin
|
|
assert(std::randomize(func7 ) with {!(func7 inside {7'h0, 7'h20});});
|
|
end
|
|
else begin
|
|
assert(std::randomize(func7 ) with { (func7 inside {7'h0, 7'h20});});
|
|
end
|
|
if(mutation[8] & !(|mutation[5:0])) begin
|
|
assert(std::randomize(opcode ) with {!(opcode inside {
|
|
LOAD_OPCODE,
|
|
MISC_MEM_OPCODE,
|
|
OP_IMM_OPCODE,
|
|
AUIPC_OPCODE,
|
|
STORE_OPCODE,
|
|
OP_OPCODE,
|
|
LUI_OPCODE,
|
|
BRANCH_OPCODE,
|
|
JALR_OPCODE,
|
|
JAL_OPCODE,
|
|
SYSTEM_OPCODE
|
|
});});
|
|
end
|
|
else begin
|
|
assert(std::randomize(opcode ) with { (opcode inside {
|
|
LOAD_OPCODE,
|
|
MISC_MEM_OPCODE,
|
|
OP_IMM_OPCODE,
|
|
AUIPC_OPCODE,
|
|
STORE_OPCODE,
|
|
OP_OPCODE,
|
|
LUI_OPCODE,
|
|
BRANCH_OPCODE,
|
|
JALR_OPCODE,
|
|
JAL_OPCODE,
|
|
SYSTEM_OPCODE
|
|
});});
|
|
end
|
|
if(mutation[7] & !(|mutation[5:0])) begin
|
|
assert(std::randomize(low_bits ) with {!(low_bits == 2'b11);});
|
|
end
|
|
else begin
|
|
assert(std::randomize(low_bits ) with { (low_bits == 2'b11);});
|
|
end
|
|
assert(std::randomize(func3)); assert(std::randomize(rs1)); assert(std::randomize(rs2)); assert(std::randomize(rd));
|
|
@(posedge clk);
|
|
fetched_instr_i <= {func7, rs2, rs1, func3, rd, opcode, low_bits};
|
|
end
|
|
endtask
|
|
|
|
bit test_paused_by_errs;
|
|
initial begin
|
|
clk = '0;
|
|
test_has_been_finished = '0;
|
|
err_count = '0;
|
|
test_paused_by_errs = '0;
|
|
end
|
|
|
|
always #5 clk = ~clk;
|
|
always @(posedge clk) begin
|
|
if(test_has_been_finished) begin
|
|
$finish();
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if((err_count >= 10) & !test_paused_by_errs) begin
|
|
test_paused_by_errs = '1;
|
|
$display("\nTest has been stopped after 10 errors");
|
|
$stop();
|
|
end
|
|
end
|
|
|
|
logic [1:0] a_sel_o;
|
|
logic [2:0] b_sel_o;
|
|
logic [4:0] alu_op_o;
|
|
logic [2:0] csr_op_o;
|
|
logic csr_we_o;
|
|
logic mem_req_o;
|
|
logic mem_we_o;
|
|
logic [2:0] mem_size_o;
|
|
logic gpr_we_o;
|
|
logic [1:0] wb_sel_o;
|
|
logic illegal_instr_o;
|
|
logic branch_o;
|
|
logic jal_o;
|
|
logic jalr_o;
|
|
logic mret_o;
|
|
|
|
logic [1:0] grm_a_sel_o;
|
|
logic [2:0] grm_b_sel_o;
|
|
logic [4:0] grm_alu_op_o;
|
|
logic [2:0] grm_csr_op_o;
|
|
logic grm_csr_we_o;
|
|
logic grm_mem_req_o;
|
|
logic grm_mem_we_o;
|
|
logic [2:0] grm_mem_size_o;
|
|
logic grm_gpr_we_o;
|
|
logic [1:0] grm_wb_sel_o;
|
|
logic grm_illegal_instr_o;
|
|
logic grm_branch_o;
|
|
logic grm_jal_o;
|
|
logic grm_jalr_o;
|
|
logic grm_mret_o;
|
|
|
|
|
|
decoder_riscv DUT(.*);
|
|
|
|
decoder_riscv_ref GRM(
|
|
.fetched_instr_i (fetched_instr_i ),
|
|
.a_sel_o (grm_a_sel_o ),
|
|
.b_sel_o (grm_b_sel_o ),
|
|
.alu_op_o (grm_alu_op_o ),
|
|
.csr_op_o (grm_csr_op_o ),
|
|
.csr_we_o (grm_csr_we_o ),
|
|
.mem_req_o (grm_mem_req_o ),
|
|
.mem_we_o (grm_mem_we_o ),
|
|
.mem_size_o (grm_mem_size_o ),
|
|
.gpr_we_o (grm_gpr_we_o ),
|
|
.wb_sel_o (grm_wb_sel_o ),
|
|
.illegal_instr_o (grm_illegal_instr_o),
|
|
.branch_o (grm_branch_o ),
|
|
.jal_o (grm_jal_o ),
|
|
.jalr_o (grm_jalr_o ),
|
|
.mret_o (grm_mret_o )
|
|
);
|
|
|
|
logic [4:0] opcode;
|
|
logic [2:0] func3;
|
|
|
|
logic a_sel_check ;
|
|
logic b_sel_check ;
|
|
logic alu_op_check ;
|
|
logic csr_op_check ;
|
|
logic csr_we_check ;
|
|
logic mem_req_check ;
|
|
logic mem_we_check ;
|
|
logic mem_size_check;
|
|
logic gpr_we_check ;
|
|
logic wb_sel_check ;
|
|
logic branch_check ;
|
|
logic jal_check ;
|
|
logic jalr_check ;
|
|
logic mret_check ;
|
|
|
|
assign opcode = fetched_instr_i[6:2];
|
|
assign func3 = fetched_instr_i[14:12];
|
|
|
|
assign a_sel_check = !(opcode inside {MISC_MEM_OPCODE, SYSTEM_OPCODE});
|
|
assign b_sel_check = !(opcode inside {MISC_MEM_OPCODE, SYSTEM_OPCODE});
|
|
assign alu_op_check = !(opcode inside {MISC_MEM_OPCODE, SYSTEM_OPCODE});
|
|
assign csr_op_check = (opcode == SYSTEM_OPCODE) && (func3 != 3'd0);
|
|
assign csr_we_check = 1'b1;
|
|
assign mem_req_check = 1'b1;
|
|
assign mem_we_check = 1'b1;
|
|
assign mem_size_check = (opcode inside {LOAD_OPCODE, STORE_OPCODE});
|
|
assign gpr_we_check = 1'b1;
|
|
assign wb_sel_check = !(opcode inside {MISC_MEM_OPCODE, BRANCH_OPCODE}) && (!(opcode == SYSTEM_OPCODE) | ((opcode == SYSTEM_OPCODE) & (func3 != 3'd0))); // (opcode == SYSTEM_OPCODE) -> (func3 != 3'd0)
|
|
assign branch_check = 1'b1;
|
|
assign jal_check = 1'b1;
|
|
assign jalr_check = 1'b1;
|
|
assign mret_check = 1'b1;
|
|
|
|
string instr_str;
|
|
string raw_instr;
|
|
|
|
illegal_instr_prop: assert property(
|
|
@(posedge clk)
|
|
(grm_illegal_instr_o === illegal_instr_o)
|
|
)
|
|
else begin
|
|
$display("illegal_instr_o value is incorrect ( %b instead of %b), instruction: %s %s", illegal_instr_o, grm_illegal_instr_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
a_sel_prop : assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
a_sel_check |-> (grm_a_sel_o === a_sel_o )
|
|
)
|
|
else begin
|
|
$display("a_sel_o value is incorrect ( %02b instead of %02b), instruction: %s %s", a_sel_o , grm_a_sel_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
b_sel_prop : assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
b_sel_check |-> (grm_b_sel_o === b_sel_o )
|
|
)
|
|
else begin
|
|
$display("b_sel_o value is incorrect ( %03b instead of %03b), instruction: %s %s", b_sel_o , grm_b_sel_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
alu_op_prop : assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
alu_op_check |-> (grm_alu_op_o === alu_op_o )
|
|
)
|
|
else begin
|
|
$display("alu_op_o value is incorrect (%05b instead of %05b), instruction: %s %s", alu_op_o , grm_alu_op_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
csr_op_prop : assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
csr_op_check |-> (grm_csr_op_o === csr_op_o )
|
|
)
|
|
else begin
|
|
$display("csr_op_o value is incorrect ( %03b instead of %03b), instruction: %s %s", csr_op_o , grm_csr_op_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
csr_we_prop : assert property (
|
|
@(posedge clk)
|
|
csr_we_check |-> (grm_csr_we_o === csr_we_o )
|
|
)
|
|
else begin
|
|
$display("csr_we_o value is incorrect ( %b instead of %b), instruction: %s %s", csr_we_o , grm_csr_we_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
mem_req_prop : assert property (
|
|
@(posedge clk)
|
|
mem_req_check |-> (grm_mem_req_o === mem_req_o )
|
|
)
|
|
else begin
|
|
$display("mem_req_o value is incorrect ( %b instead of %b), instruction: %s %s", mem_req_o , grm_mem_req_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
mem_we_prop : assert property (
|
|
@(posedge clk)
|
|
mem_we_check |-> (grm_mem_we_o === mem_we_o )
|
|
)
|
|
else begin
|
|
$display("mem_we_o value is incorrect ( %b instead of %b), instruction: %s %s", mem_we_o , grm_mem_we_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
mem_size_prop: assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
mem_size_check |-> (grm_mem_size_o === mem_size_o)
|
|
)
|
|
else begin
|
|
$display("mem_size_o value is incorrect ( %03b instead of %03b), instruction: %s %s", mem_size_o, grm_mem_size_o, raw_instr, instr_str);
|
|
err_count++;
|
|
end
|
|
|
|
gpr_we_prop : assert property (
|
|
@(posedge clk)
|
|
gpr_we_check |-> (grm_gpr_we_o === gpr_we_o )
|
|
)
|
|
else begin
|
|
$display("gpr_we_o value is incorrect ( %b instead of %b), instruction: %s %s", gpr_we_o , grm_gpr_we_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
wb_sel_prop : assert property (
|
|
@(posedge clk) disable iff(grm_illegal_instr_o)
|
|
wb_sel_check |-> (grm_wb_sel_o === wb_sel_o )
|
|
)
|
|
else begin
|
|
$display("wb_sel_o value is incorrect ( %b instead of %b), instruction: %s %s", wb_sel_o , grm_wb_sel_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
branch_prop : assert property (
|
|
@(posedge clk)
|
|
branch_check |-> (grm_branch_o === branch_o )
|
|
)
|
|
else begin
|
|
$display("branch_o value is incorrect ( %b instead of %b), instruction: %s %s", branch_o , grm_branch_o, raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
jal_prop : assert property (
|
|
@(posedge clk)
|
|
jal_check |-> (grm_jal_o === jal_o )
|
|
)
|
|
else begin
|
|
$display("jal_o value is incorrect ( %b instead of %b), instruction: %s %s", jal_o , grm_jal_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
jalr_prop : assert property (
|
|
@(posedge clk)
|
|
jalr_check |-> (grm_jalr_o === jalr_o )
|
|
)
|
|
else begin
|
|
$display("jalr_o value is incorrect ( %b instead of %b), instruction: %s %s", jalr_o , grm_jalr_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
mret_prop : assert property (
|
|
@(posedge clk)
|
|
mret_check |-> (grm_mret_o === mret_o )
|
|
)
|
|
else begin
|
|
$display("mret_o value is incorrect ( %b instead of %b), instruction: %s %s", mret_o , grm_mret_o , raw_instr, instr_str );
|
|
err_count++;
|
|
end
|
|
|
|
always_comb begin
|
|
case (opcode)
|
|
LUI_OPCODE, AUIPC_OPCODE, JAL_OPCODE:
|
|
raw_instr = $sformatf("%020b %05b %07b " , fetched_instr_i[31:12], fetched_instr_i[11:7], fetched_instr_i[6:0]);
|
|
JALR_OPCODE, LOAD_OPCODE, OP_IMM_OPCODE, SYSTEM_OPCODE:
|
|
raw_instr = $sformatf("%012b %05b %03b %05b %07b " , fetched_instr_i[31:20], fetched_instr_i[19:15], fetched_instr_i[14:12], fetched_instr_i[11:7], fetched_instr_i[6:0]);
|
|
BRANCH_OPCODE, STORE_OPCODE, OP_OPCODE:
|
|
raw_instr = $sformatf("%07b %05b %05b %03b %05b %07b", fetched_instr_i[31:25], fetched_instr_i[24:20], fetched_instr_i[19:15], fetched_instr_i[14:12], fetched_instr_i[11:7], fetched_instr_i[6:0]);
|
|
MISC_MEM_OPCODE:
|
|
raw_instr = $sformatf("%017b %03b %05b %07b " , fetched_instr_i[31:15], fetched_instr_i[14:12], fetched_instr_i[11:7], fetched_instr_i[6:0]);
|
|
default:
|
|
raw_instr = $sformatf("%032b " , fetched_instr_i);
|
|
endcase
|
|
end
|
|
|
|
always_comb begin
|
|
if(&fetched_instr_i[1:0])
|
|
case(opcode)
|
|
LUI_OPCODE: begin
|
|
instr_str = "( LUI )";
|
|
end
|
|
AUIPC_OPCODE: begin
|
|
instr_str = "( AUIPC )";
|
|
end
|
|
JAL_OPCODE: begin
|
|
instr_str = "( JAL )";
|
|
end
|
|
JALR_OPCODE: begin
|
|
instr_str = func3? "( illegal_JALR )": "( JALR )";
|
|
end
|
|
BRANCH_OPCODE: begin
|
|
case(func3)
|
|
3'b000: instr_str = "( BEQ )";
|
|
3'b001: instr_str = "( BNE )";
|
|
3'b100: instr_str = "( BLT )";
|
|
3'b101: instr_str = "( BGE )";
|
|
3'b110: instr_str = "( BLTU )";
|
|
3'b111: instr_str = "( BGEU )";
|
|
default: instr_str= "(illegal_BRANCH)";
|
|
endcase
|
|
end
|
|
LOAD_OPCODE: begin
|
|
case(func3)
|
|
3'b000: instr_str = "( LB )";
|
|
3'b001: instr_str = "( LH )";
|
|
3'b010: instr_str = "( LW )";
|
|
3'b100: instr_str = "( LBU )";
|
|
3'b101: instr_str = "( LHU )";
|
|
default: instr_str= "( illegal_LOAD )";
|
|
endcase
|
|
end
|
|
STORE_OPCODE: begin
|
|
case(func3)
|
|
3'b000: instr_str = "( SB )";
|
|
3'b001: instr_str = "( SH )";
|
|
3'b010: instr_str = "( SW )";
|
|
default: instr_str = "(illegal_STORE)";
|
|
endcase
|
|
end
|
|
OP_IMM_OPCODE: begin
|
|
case({2'b0,func3})
|
|
ALU_ADD : instr_str = "( ADDI )";
|
|
ALU_XOR : instr_str = "( XORI )";
|
|
ALU_OR : instr_str = "( ORI )";
|
|
ALU_AND : instr_str = "( ANDI )";
|
|
ALU_SRL : instr_str = {fetched_instr_i[31],fetched_instr_i[29:25]}? "(illegal_OP_IMM)": fetched_instr_i[30]? "( SRAI )": "( SRLI )";
|
|
ALU_SLL : instr_str = fetched_instr_i[31:25]? "(illegal_OP_IMM)": "( SLLI )";
|
|
ALU_SLTS : instr_str = "( SLTI )";
|
|
ALU_SLTU : instr_str = "( SLTIU )";
|
|
default : instr_str = "(illegal_OP_IMM)";
|
|
endcase
|
|
end
|
|
OP_OPCODE: begin
|
|
if(!fetched_instr_i[29:25])
|
|
case({fetched_instr_i[31:30], func3})
|
|
ALU_ADD : instr_str = "( ADD )";
|
|
ALU_SUB : instr_str = "( SUB )";
|
|
ALU_XOR : instr_str = "( XOR )";
|
|
ALU_OR : instr_str = "( OR )";
|
|
ALU_AND : instr_str = "( AND )";
|
|
ALU_SRA : instr_str = "( SRA )";
|
|
ALU_SRL : instr_str = "( SRL )";
|
|
ALU_SLL : instr_str = "( SLL )";
|
|
ALU_SLTU : instr_str = "( SLTU )";
|
|
default : instr_str = "( illegal_OP )";
|
|
endcase
|
|
else instr_str = "( illegal_OP )";
|
|
end
|
|
MISC_MEM_OPCODE: begin
|
|
instr_str = func3 ? "(illegal_FENCE )": "( FENCE )";
|
|
end
|
|
SYSTEM_OPCODE: begin
|
|
instr_str = "(illegal_SYSTEM)";
|
|
case(func3)
|
|
3'd0: begin
|
|
case(fetched_instr_i)
|
|
32'h000_0_0_0_73: instr_str = "( ECALL )";
|
|
32'h001_0_0_0_73: instr_str = "( EBREAK )";
|
|
32'h302_0_0_0_73: instr_str = "( MRET )";
|
|
endcase
|
|
end
|
|
3'd1: instr_str = "( CSRRW )";
|
|
3'd2: instr_str = "( CSRRS )";
|
|
3'd3: instr_str = "( CSRRC )";
|
|
3'd5: instr_str = "( CSRRWI )";
|
|
3'd6: instr_str = "( CSRRSI )";
|
|
3'd7: instr_str = "( CSRRCI )";
|
|
endcase
|
|
end
|
|
default: instr_str = "(illegal_opcode)";
|
|
endcase
|
|
else instr_str = "(illegal_opcode)";
|
|
end
|
|
|
|
class riscv_instr;
|
|
rand bit [20:0] imm;
|
|
rand bit [ 6:0] func7;
|
|
rand bit [ 4:0] shamt;
|
|
rand bit [ 4:0] rs2;
|
|
rand bit [ 4:0] rs1;
|
|
rand bit [ 2:0] func3;
|
|
rand bit [ 4:0] rd;
|
|
rand bit [ 4:0] opcode;
|
|
|
|
bit [31:0] bits;
|
|
|
|
bit [31:0] system_instrs[3] = {
|
|
32'h000_0_0_0_73, //ecall
|
|
32'h001_0_0_0_73, //ebreak
|
|
32'h302_0_0_0_73 //mret
|
|
};
|
|
|
|
constraint valid_opcode {opcode inside { LOAD_OPCODE,
|
|
MISC_MEM_OPCODE,
|
|
OP_IMM_OPCODE,
|
|
AUIPC_OPCODE,
|
|
STORE_OPCODE,
|
|
OP_OPCODE,
|
|
LUI_OPCODE,
|
|
BRANCH_OPCODE,
|
|
JALR_OPCODE,
|
|
JAL_OPCODE,
|
|
SYSTEM_OPCODE
|
|
};}
|
|
|
|
constraint load_opcode { (opcode == LOAD_OPCODE ) -> !(func3 inside {3'h3, 3'h6, 3'h7});}
|
|
|
|
constraint misc_mem_opcode { (opcode == MISC_MEM_OPCODE) -> (func3 == 3'b000);}
|
|
|
|
constraint op_imm_opcode1 {((opcode == OP_IMM_OPCODE ) && (func3 == 3'h1)) -> (func7 == 7'h00);}
|
|
constraint op_imm_opcode2 {((opcode == OP_IMM_OPCODE ) && (func3 == 3'h5)) -> (func7 inside {7'h00, 7'h20});}
|
|
|
|
constraint store_opcode { (opcode == STORE_OPCODE ) -> (func3 inside {3'h0, 3'h1, 3'h2});}
|
|
|
|
constraint op_opcode1 {((opcode == OP_OPCODE ) && (func3 inside {3'b000, 3'b101})) -> (func7 inside {7'h00, 7'h20});}
|
|
constraint op_opcode2 {((opcode == OP_OPCODE ) && !(func3 inside {3'b000, 3'b101})) -> (func7 == 7'h00);}
|
|
|
|
constraint branch_opcode { (opcode == BRANCH_OPCODE ) -> !(func3 inside {3'h2, 3'h3});}
|
|
|
|
constraint jalr_opcode { (opcode == JALR_OPCODE ) -> (func3 == 3'h0);}
|
|
|
|
constraint system_opcode { (opcode == SYSTEM_OPCODE ) -> !(func3 == 3'h4);}
|
|
|
|
function void post_randomize();
|
|
case(opcode)
|
|
LOAD_OPCODE, MISC_MEM_OPCODE, JALR_OPCODE: begin
|
|
bits = {imm[11:0], rs1, func3, rd, opcode, 2'b11};
|
|
end
|
|
OP_IMM_OPCODE: begin
|
|
if(func3 inside {3'h1, 3'h5}) begin
|
|
bits = {func7, shamt, rs1, func3, rd, opcode, 2'b11};
|
|
end
|
|
else begin
|
|
bits = {imm[11:0], rs1, func3, rd, opcode, 2'b11};
|
|
end
|
|
end
|
|
AUIPC_OPCODE, LUI_OPCODE: begin
|
|
bits = {imm, opcode, 2'b11};
|
|
end
|
|
STORE_OPCODE: begin
|
|
bits = {imm[11:5], rs2, rs1, func3, imm[4:0], opcode, 2'b11};
|
|
end
|
|
OP_OPCODE: begin
|
|
bits = {func7, rs2, rs1, func3, rd, opcode, 2'b11};
|
|
end
|
|
BRANCH_OPCODE: begin
|
|
bits = {imm[12], imm[10:5], rs2, rs1, func3, imm[4:1], imm[11], opcode, 2'b11};
|
|
end
|
|
JAL_OPCODE: begin
|
|
bits = {imm[20], imm[10:1], imm[11], imm[19:12], rd, opcode, 2'b11};
|
|
end
|
|
SYSTEM_OPCODE: begin
|
|
if(func3 == 3'h0) begin
|
|
bits = system_instrs[$urandom_range(3)];
|
|
end
|
|
else begin
|
|
bits = {imm[11:0], rs1, func3, rd, opcode, 2'b11};
|
|
end
|
|
end
|
|
default: begin
|
|
$fatal(1, "Missing opcode %0h in post_randomize", opcode);
|
|
end
|
|
endcase
|
|
endfunction
|
|
|
|
endclass
|
|
|
|
endmodule
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Project Name : Architectures of Processor Systems (APS) lab work
|
|
* Organization : National Research University of Electronic Technology (MIET)
|
|
* Department : Institute of Microdevices and Control Systems
|
|
* Author(s) : Alexey Kozin
|
|
* Email(s) : @edu.miet.ru
|
|
|
|
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
|
* ------------------------------------------------------------------------------
|
|
*/
|
|
module gpr_we_table (gis_ew_rpg, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_ew_rpg;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_ew_rpg = 1'b1;
|
|
5'b00001: gis_ew_rpg = 1'b0;
|
|
5'b00010: gis_ew_rpg = 1'b0;
|
|
5'b00011: gis_ew_rpg = 1'b0;
|
|
5'b00100: gis_ew_rpg = 1'b1;
|
|
5'b00101: gis_ew_rpg = 1'b1;
|
|
5'b00110: gis_ew_rpg = 1'b0;
|
|
5'b00111: gis_ew_rpg = 1'b0;
|
|
5'b01000: gis_ew_rpg = 1'b0;
|
|
5'b01001: gis_ew_rpg = 1'b0;
|
|
5'b01010: gis_ew_rpg = 1'b0;
|
|
5'b01011: gis_ew_rpg = 1'b0;
|
|
5'b01100: gis_ew_rpg = 1'b1;
|
|
5'b01101: gis_ew_rpg = 1'b1;
|
|
5'b01110: gis_ew_rpg = 1'b0;
|
|
5'b01111: gis_ew_rpg = 1'b0;
|
|
5'b10000: gis_ew_rpg = 1'b0;
|
|
5'b10001: gis_ew_rpg = 1'b0;
|
|
5'b10010: gis_ew_rpg = 1'b0;
|
|
5'b10011: gis_ew_rpg = 1'b0;
|
|
5'b10100: gis_ew_rpg = 1'b0;
|
|
5'b10101: gis_ew_rpg = 1'b0;
|
|
5'b10110: gis_ew_rpg = 1'b0;
|
|
5'b10111: gis_ew_rpg = 1'b0;
|
|
5'b11000: gis_ew_rpg = 1'b0;
|
|
5'b11001: gis_ew_rpg = 1'b1;
|
|
5'b11010: gis_ew_rpg = 1'b0;
|
|
5'b11011: gis_ew_rpg = 1'b1;
|
|
5'b11100: gis_ew_rpg = 1'b1;
|
|
5'b11101: gis_ew_rpg = 1'b0;
|
|
5'b11110: gis_ew_rpg = 1'b0;
|
|
5'b11111: gis_ew_rpg = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module csr_we_table (gis_ew_rsc, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_ew_rsc;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_ew_rsc = 1'b0;
|
|
5'b00001: gis_ew_rsc = 1'b0;
|
|
5'b00010: gis_ew_rsc = 1'b0;
|
|
5'b00011: gis_ew_rsc = 1'b0;
|
|
5'b00100: gis_ew_rsc = 1'b0;
|
|
5'b00101: gis_ew_rsc = 1'b0;
|
|
5'b00110: gis_ew_rsc = 1'b0;
|
|
5'b00111: gis_ew_rsc = 1'b0;
|
|
5'b01000: gis_ew_rsc = 1'b0;
|
|
5'b01001: gis_ew_rsc = 1'b0;
|
|
5'b01010: gis_ew_rsc = 1'b0;
|
|
5'b01011: gis_ew_rsc = 1'b0;
|
|
5'b01100: gis_ew_rsc = 1'b0;
|
|
5'b01101: gis_ew_rsc = 1'b0;
|
|
5'b01110: gis_ew_rsc = 1'b0;
|
|
5'b01111: gis_ew_rsc = 1'b0;
|
|
5'b10000: gis_ew_rsc = 1'b0;
|
|
5'b10001: gis_ew_rsc = 1'b0;
|
|
5'b10010: gis_ew_rsc = 1'b0;
|
|
5'b10011: gis_ew_rsc = 1'b0;
|
|
5'b10100: gis_ew_rsc = 1'b0;
|
|
5'b10101: gis_ew_rsc = 1'b0;
|
|
5'b10110: gis_ew_rsc = 1'b0;
|
|
5'b10111: gis_ew_rsc = 1'b0;
|
|
5'b11000: gis_ew_rsc = 1'b0;
|
|
5'b11001: gis_ew_rsc = 1'b0;
|
|
5'b11010: gis_ew_rsc = 1'b0;
|
|
5'b11011: gis_ew_rsc = 1'b0;
|
|
5'b11100: gis_ew_rsc = 1'b1;
|
|
5'b11101: gis_ew_rsc = 1'b0;
|
|
5'b11110: gis_ew_rsc = 1'b0;
|
|
5'b11111: gis_ew_rsc = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module mem_req_table (gis_qer_mem, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_qer_mem;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_qer_mem = 1'b1;
|
|
5'b00001: gis_qer_mem = 1'b0;
|
|
5'b00010: gis_qer_mem = 1'b0;
|
|
5'b00011: gis_qer_mem = 1'b0;
|
|
5'b00100: gis_qer_mem = 1'b0;
|
|
5'b00101: gis_qer_mem = 1'b0;
|
|
5'b00110: gis_qer_mem = 1'b0;
|
|
5'b00111: gis_qer_mem = 1'b0;
|
|
5'b01000: gis_qer_mem = 1'b1;
|
|
5'b01001: gis_qer_mem = 1'b0;
|
|
5'b01010: gis_qer_mem = 1'b0;
|
|
5'b01011: gis_qer_mem = 1'b0;
|
|
5'b01100: gis_qer_mem = 1'b0;
|
|
5'b01101: gis_qer_mem = 1'b0;
|
|
5'b01110: gis_qer_mem = 1'b0;
|
|
5'b01111: gis_qer_mem = 1'b0;
|
|
5'b10000: gis_qer_mem = 1'b0;
|
|
5'b10001: gis_qer_mem = 1'b0;
|
|
5'b10010: gis_qer_mem = 1'b0;
|
|
5'b10011: gis_qer_mem = 1'b0;
|
|
5'b10100: gis_qer_mem = 1'b0;
|
|
5'b10101: gis_qer_mem = 1'b0;
|
|
5'b10110: gis_qer_mem = 1'b0;
|
|
5'b10111: gis_qer_mem = 1'b0;
|
|
5'b11000: gis_qer_mem = 1'b0;
|
|
5'b11001: gis_qer_mem = 1'b0;
|
|
5'b11010: gis_qer_mem = 1'b0;
|
|
5'b11011: gis_qer_mem = 1'b0;
|
|
5'b11100: gis_qer_mem = 1'b0;
|
|
5'b11101: gis_qer_mem = 1'b0;
|
|
5'b11110: gis_qer_mem = 1'b0;
|
|
5'b11111: gis_qer_mem = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module mem_we_table (gis_ew_mem, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_ew_mem;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_ew_mem = 1'b0;
|
|
5'b00001: gis_ew_mem = 1'b0;
|
|
5'b00010: gis_ew_mem = 1'b0;
|
|
5'b00011: gis_ew_mem = 1'b0;
|
|
5'b00100: gis_ew_mem = 1'b0;
|
|
5'b00101: gis_ew_mem = 1'b0;
|
|
5'b00110: gis_ew_mem = 1'b0;
|
|
5'b00111: gis_ew_mem = 1'b0;
|
|
5'b01000: gis_ew_mem = 1'b1;
|
|
5'b01001: gis_ew_mem = 1'b0;
|
|
5'b01010: gis_ew_mem = 1'b0;
|
|
5'b01011: gis_ew_mem = 1'b0;
|
|
5'b01100: gis_ew_mem = 1'b0;
|
|
5'b01101: gis_ew_mem = 1'b0;
|
|
5'b01110: gis_ew_mem = 1'b0;
|
|
5'b01111: gis_ew_mem = 1'b0;
|
|
5'b10000: gis_ew_mem = 1'b0;
|
|
5'b10001: gis_ew_mem = 1'b0;
|
|
5'b10010: gis_ew_mem = 1'b0;
|
|
5'b10011: gis_ew_mem = 1'b0;
|
|
5'b10100: gis_ew_mem = 1'b0;
|
|
5'b10101: gis_ew_mem = 1'b0;
|
|
5'b10110: gis_ew_mem = 1'b0;
|
|
5'b10111: gis_ew_mem = 1'b0;
|
|
5'b11000: gis_ew_mem = 1'b0;
|
|
5'b11001: gis_ew_mem = 1'b0;
|
|
5'b11010: gis_ew_mem = 1'b0;
|
|
5'b11011: gis_ew_mem = 1'b0;
|
|
5'b11100: gis_ew_mem = 1'b0;
|
|
5'b11101: gis_ew_mem = 1'b0;
|
|
5'b11110: gis_ew_mem = 1'b0;
|
|
5'b11111: gis_ew_mem = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module branch_table (gis_hcnarb, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_hcnarb;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_hcnarb = 1'b0;
|
|
5'b00001: gis_hcnarb = 1'b0;
|
|
5'b00010: gis_hcnarb = 1'b0;
|
|
5'b00011: gis_hcnarb = 1'b0;
|
|
5'b00100: gis_hcnarb = 1'b0;
|
|
5'b00101: gis_hcnarb = 1'b0;
|
|
5'b00110: gis_hcnarb = 1'b0;
|
|
5'b00111: gis_hcnarb = 1'b0;
|
|
5'b01000: gis_hcnarb = 1'b0;
|
|
5'b01001: gis_hcnarb = 1'b0;
|
|
5'b01010: gis_hcnarb = 1'b0;
|
|
5'b01011: gis_hcnarb = 1'b0;
|
|
5'b01100: gis_hcnarb = 1'b0;
|
|
5'b01101: gis_hcnarb = 1'b0;
|
|
5'b01110: gis_hcnarb = 1'b0;
|
|
5'b01111: gis_hcnarb = 1'b0;
|
|
5'b10000: gis_hcnarb = 1'b0;
|
|
5'b10001: gis_hcnarb = 1'b0;
|
|
5'b10010: gis_hcnarb = 1'b0;
|
|
5'b10011: gis_hcnarb = 1'b0;
|
|
5'b10100: gis_hcnarb = 1'b0;
|
|
5'b10101: gis_hcnarb = 1'b0;
|
|
5'b10110: gis_hcnarb = 1'b0;
|
|
5'b10111: gis_hcnarb = 1'b0;
|
|
5'b11000: gis_hcnarb = 1'b1;
|
|
5'b11001: gis_hcnarb = 1'b0;
|
|
5'b11010: gis_hcnarb = 1'b0;
|
|
5'b11011: gis_hcnarb = 1'b0;
|
|
5'b11100: gis_hcnarb = 1'b0;
|
|
5'b11101: gis_hcnarb = 1'b0;
|
|
5'b11110: gis_hcnarb = 1'b0;
|
|
5'b11111: gis_hcnarb = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module jalr_table (gis_rlaj, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
output logic gis_rlaj;
|
|
input edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2;
|
|
always_comb
|
|
case({edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2})
|
|
5'b00000: gis_rlaj = 1'b0;
|
|
5'b00001: gis_rlaj = 1'b0;
|
|
5'b00010: gis_rlaj = 1'b0;
|
|
5'b00011: gis_rlaj = 1'b0;
|
|
5'b00100: gis_rlaj = 1'b0;
|
|
5'b00101: gis_rlaj = 1'b0;
|
|
5'b00110: gis_rlaj = 1'b0;
|
|
5'b00111: gis_rlaj = 1'b0;
|
|
5'b01000: gis_rlaj = 1'b0;
|
|
5'b01001: gis_rlaj = 1'b0;
|
|
5'b01010: gis_rlaj = 1'b0;
|
|
5'b01011: gis_rlaj = 1'b0;
|
|
5'b01100: gis_rlaj = 1'b0;
|
|
5'b01101: gis_rlaj = 1'b0;
|
|
5'b01110: gis_rlaj = 1'b0;
|
|
5'b01111: gis_rlaj = 1'b0;
|
|
5'b10000: gis_rlaj = 1'b0;
|
|
5'b10001: gis_rlaj = 1'b0;
|
|
5'b10010: gis_rlaj = 1'b0;
|
|
5'b10011: gis_rlaj = 1'b0;
|
|
5'b10100: gis_rlaj = 1'b0;
|
|
5'b10101: gis_rlaj = 1'b0;
|
|
5'b10110: gis_rlaj = 1'b0;
|
|
5'b10111: gis_rlaj = 1'b0;
|
|
5'b11000: gis_rlaj = 1'b0;
|
|
5'b11001: gis_rlaj = 1'b1;
|
|
5'b11010: gis_rlaj = 1'b0;
|
|
5'b11011: gis_rlaj = 1'b0;
|
|
5'b11100: gis_rlaj = 1'b0;
|
|
5'b11101: gis_rlaj = 1'b0;
|
|
5'b11110: gis_rlaj = 1'b0;
|
|
5'b11111: gis_rlaj = 1'b0;
|
|
endcase
|
|
endmodule
|
|
|
|
module decoder_riscv_ref (
|
|
input logic [31:0] fetched_instr_i,
|
|
output logic [1:0] a_sel_o,
|
|
output logic [2:0] b_sel_o,
|
|
output logic [4:0] alu_op_o,
|
|
output logic [2:0] csr_op_o,
|
|
output logic csr_we_o,
|
|
output logic mem_req_o,
|
|
output logic mem_we_o,
|
|
output logic [2:0] mem_size_o,
|
|
output logic gpr_we_o,
|
|
output logic [1:0] wb_sel_o,
|
|
output logic illegal_instr_o,
|
|
output logic branch_o,
|
|
output logic jal_o,
|
|
output logic jalr_o,
|
|
output logic mret_o
|
|
);
|
|
|
|
logic [4:0] epyt_r;
|
|
logic [4:0] htira_epyt_i;
|
|
logic [4:0] daol_epyt_i;
|
|
logic [4:0] rlaj_epyt_i;
|
|
logic [4:0] ecnef_epyt_i;
|
|
logic [4:0] rsc_epyt_i;
|
|
logic [4:0] epyt_s;
|
|
logic [4:0] epyt_b;
|
|
logic [4:0] iul_epyt_u;
|
|
logic [4:0] cpiua_epyt_u;
|
|
logic [4:0] epyt_j;
|
|
|
|
logic [4:0] edocpo;
|
|
logic [1:0] bsl;
|
|
logic [6:0] tcnuf_7;
|
|
logic [2:0] tcnuf_3;
|
|
|
|
logic po_dda;
|
|
logic po_bus;
|
|
logic po_rox;
|
|
logic po_ro;
|
|
logic po_dna;
|
|
logic po_lls;
|
|
logic po_lrs;
|
|
logic po_ars;
|
|
logic po_tls;
|
|
logic po_utls;
|
|
logic po_idda;
|
|
logic po_irox;
|
|
logic po_iro;
|
|
logic po_idna;
|
|
logic po_ills;
|
|
logic po_ilrs;
|
|
logic po_iars;
|
|
logic po_itls;
|
|
logic po_uitls;
|
|
logic po_bl;
|
|
logic po_hl;
|
|
logic po_wl;
|
|
logic po_ubl;
|
|
logic po_uhl;
|
|
logic po_bs;
|
|
logic po_hs;
|
|
logic po_ws;
|
|
logic po_qeb;
|
|
logic po_enb;
|
|
logic po_tlb;
|
|
logic po_egb;
|
|
logic po_utlb;
|
|
logic po_uegb;
|
|
logic po_laj;
|
|
logic po_rlaj;
|
|
logic po_iul;
|
|
logic po_cpiua;
|
|
logic po_ecnef;
|
|
logic po_llace;
|
|
logic po_kaerbe;
|
|
logic po_term;
|
|
logic po_wrssc;
|
|
logic po_srssc;
|
|
logic po_crssc;
|
|
logic po_iwrssc;
|
|
logic po_isrssc;
|
|
logic po_icrssc;
|
|
|
|
logic po_htira;
|
|
logic po_mmi;
|
|
logic po_daol;
|
|
logic po_erots;
|
|
logic po_hcnarb;
|
|
logic po_vne;
|
|
logic po_rsc;
|
|
|
|
logic gis_ew_rsc;
|
|
logic gis_ew_rsc_erp;
|
|
logic gis_qer_mem;
|
|
logic gis_ew_mem;
|
|
logic gis_ew_rpg;
|
|
logic gis_ew_rpg_erp;
|
|
logic gis_hcnarb;
|
|
logic gis_rlaj;
|
|
|
|
csr_we_table block_a (gis_ew_rsc_erp, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
mem_req_table block_b (gis_qer_mem, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
mem_we_table block_c (gis_ew_mem, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
gpr_we_table block_d (gis_ew_rpg_erp, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
branch_table block_e (gis_hcnarb, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
jalr_table block_f (gis_rlaj, edocpo_6, edocpo_5, edocpo_4, edocpo_3, edocpo_2);
|
|
|
|
assign gis_ew_rsc = gis_ew_rsc_erp & !illegal_instr_o & !po_term;
|
|
assign gis_ew_rpg = gis_ew_rpg_erp & !illegal_instr_o & !po_term;
|
|
|
|
assign epyt_r = 5'b01100;
|
|
assign htira_epyt_i = 5'b00100;
|
|
assign daol_epyt_i = 5'b00000;
|
|
assign rlaj_epyt_i = 5'b11001;
|
|
assign ecnef_epyt_i = 5'b00011;
|
|
assign rsc_epyt_i = 5'b11100;
|
|
assign epyt_s = 5'b01000;
|
|
assign epyt_b = 5'b11000;
|
|
assign iul_epyt_u = 5'b01101;
|
|
assign cpiua_epyt_u = 5'b00101;
|
|
assign epyt_j = 5'b11011;
|
|
|
|
assign edocpo = fetched_instr_i[6:2];
|
|
assign edocpo_6 = fetched_instr_i[6];
|
|
assign edocpo_5 = fetched_instr_i[5];
|
|
assign edocpo_4 = fetched_instr_i[4];
|
|
assign edocpo_3 = fetched_instr_i[3];
|
|
assign edocpo_2 = fetched_instr_i[2];
|
|
assign bsl = fetched_instr_i[1:0];
|
|
assign tcnuf_7 = fetched_instr_i[31:25];
|
|
assign tcnuf_3 = fetched_instr_i[14:12];
|
|
|
|
assign po_dda = edocpo == epyt_r & tcnuf_3 == 'h0 & tcnuf_7 == 'h00;
|
|
assign po_bus = edocpo == epyt_r & tcnuf_3 == 'h0 & tcnuf_7 == 'h20;
|
|
assign po_rox = edocpo == epyt_r & tcnuf_3 == 'h4 & tcnuf_7 == 'h00;
|
|
assign po_ro = edocpo == epyt_r & tcnuf_3 == 'h6 & tcnuf_7 == 'h00;
|
|
assign po_dna = edocpo == epyt_r & tcnuf_3 == 'h7 & tcnuf_7 == 'h00;
|
|
assign po_lls = edocpo == epyt_r & tcnuf_3 == 'h1 & tcnuf_7 == 'h00;
|
|
assign po_lrs = edocpo == epyt_r & tcnuf_3 == 'h5 & tcnuf_7 == 'h00;
|
|
assign po_ars = edocpo == epyt_r & tcnuf_3 == 'h5 & tcnuf_7 == 'h20;
|
|
assign po_tls = edocpo == epyt_r & tcnuf_3 == 'h2 & tcnuf_7 == 'h00;
|
|
assign po_utls = edocpo == epyt_r & tcnuf_3 == 'h3 & tcnuf_7 == 'h00;
|
|
|
|
assign po_idda = edocpo == htira_epyt_i & tcnuf_3 == 'h0 ;
|
|
assign po_irox = edocpo == htira_epyt_i & tcnuf_3 == 'h4 ;
|
|
assign po_iro = edocpo == htira_epyt_i & tcnuf_3 == 'h6 ;
|
|
assign po_idna = edocpo == htira_epyt_i & tcnuf_3 == 'h7 ;
|
|
assign po_ills = edocpo == htira_epyt_i & tcnuf_3 == 'h1 & tcnuf_7 == 'h00;
|
|
assign po_ilrs = edocpo == htira_epyt_i & tcnuf_3 == 'h5 & tcnuf_7 == 'h00;
|
|
assign po_iars = edocpo == htira_epyt_i & tcnuf_3 == 'h5 & tcnuf_7 == 'h20;
|
|
assign po_itls = edocpo == htira_epyt_i & tcnuf_3 == 'h2 ;
|
|
assign po_uitls = edocpo == htira_epyt_i & tcnuf_3 == 'h3 ;
|
|
|
|
assign po_bl = edocpo == daol_epyt_i & tcnuf_3 == 'h0 ;
|
|
assign po_hl = edocpo == daol_epyt_i & tcnuf_3 == 'h1 ;
|
|
assign po_wl = edocpo == daol_epyt_i & tcnuf_3 == 'h2 ;
|
|
assign po_ubl = edocpo == daol_epyt_i & tcnuf_3 == 'h4 ;
|
|
assign po_uhl = edocpo == daol_epyt_i & tcnuf_3 == 'h5 ;
|
|
|
|
assign po_bs = edocpo == epyt_s & tcnuf_3 == 'h0 ;
|
|
assign po_hs = edocpo == epyt_s & tcnuf_3 == 'h1 ;
|
|
assign po_ws = edocpo == epyt_s & tcnuf_3 == 'h2 ;
|
|
|
|
assign po_qeb = edocpo == epyt_b & tcnuf_3 == 'h0 ;
|
|
assign po_enb = edocpo == epyt_b & tcnuf_3 == 'h1 ;
|
|
assign po_tlb = edocpo == epyt_b & tcnuf_3 == 'h4 ;
|
|
assign po_egb = edocpo == epyt_b & tcnuf_3 == 'h5 ;
|
|
assign po_utlb = edocpo == epyt_b & tcnuf_3 == 'h6 ;
|
|
assign po_uegb = edocpo == epyt_b & tcnuf_3 == 'h7 ;
|
|
|
|
assign po_laj = edocpo == epyt_j ;
|
|
|
|
assign po_rlaj = edocpo == rlaj_epyt_i & tcnuf_3 == 'h0 ;
|
|
|
|
assign po_iul = edocpo == iul_epyt_u ;
|
|
|
|
assign po_cpiua = edocpo == cpiua_epyt_u ;
|
|
|
|
assign po_ecnef = edocpo == ecnef_epyt_i & tcnuf_3 == 'h0 ;
|
|
|
|
assign po_llace = fetched_instr_i == 32'h00000073;
|
|
assign po_kaerbe = fetched_instr_i == 32'h00100073;
|
|
|
|
assign po_term = fetched_instr_i == 32'h30200073;
|
|
|
|
assign po_wrssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h1 ;
|
|
assign po_srssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h2 ;
|
|
assign po_crssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h3 ;
|
|
assign po_iwrssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h5 ;
|
|
assign po_isrssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h6 ;
|
|
assign po_icrssc = edocpo == rsc_epyt_i & tcnuf_3 == 'h7 ;
|
|
|
|
assign po_htira = po_dda | po_bus | po_rox | po_ro | po_dna | po_lls | po_lrs | po_ars | po_tls | po_utls;
|
|
assign po_mmi = po_idda | po_irox | po_iro | po_idna | po_ills | po_ilrs | po_iars | po_itls | po_uitls;
|
|
assign po_daol = po_bl | po_hl | po_wl | po_ubl | po_uhl;
|
|
assign po_erots = po_bs | po_hs | po_ws;
|
|
assign po_hcnarb = po_qeb | po_enb | po_tlb | po_egb | po_utlb | po_uegb;
|
|
assign po_vne = po_llace | po_kaerbe;
|
|
assign po_rsc = po_wrssc | po_srssc | po_crssc | po_iwrssc | po_isrssc | po_icrssc;
|
|
|
|
always_comb begin
|
|
if (bsl == 2'b11) begin
|
|
if (po_htira) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = po_dda ? 5'b00000 :
|
|
po_bus ? 5'b01000 :
|
|
po_rox ? 5'b00100 :
|
|
po_ro ? 5'b00110 :
|
|
po_dna ? 5'b00111 :
|
|
po_lls ? 5'b00001 :
|
|
po_lrs ? 5'b00101 :
|
|
po_ars ? 5'b01101 :
|
|
po_tls ? 5'b00010 :
|
|
po_utls ? 5'b00011 :
|
|
5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_mmi) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b001;
|
|
alu_op_o = po_idda ? 5'b00000 :
|
|
po_irox ? 5'b00100 :
|
|
po_iro ? 5'b00110 :
|
|
po_idna ? 5'b00111 :
|
|
po_ills ? 5'b00001 :
|
|
po_ilrs ? 5'b00101 :
|
|
po_iars ? 5'b01101 :
|
|
po_itls ? 5'b00010 :
|
|
po_uitls ? 5'b00011 :
|
|
5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_daol) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b001;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = 1'b0;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = tcnuf_3;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b01;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_erots) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b011;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = tcnuf_3;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_hcnarb) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = po_qeb ? 5'b11000 :
|
|
po_enb ? 5'b11001 :
|
|
po_tlb ? 5'b11100 :
|
|
po_egb ? 5'b11101 :
|
|
po_utlb ? 5'b11110 :
|
|
po_uegb ? 5'b11111 :
|
|
5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_laj) begin
|
|
a_sel_o = 2'b01;
|
|
b_sel_o = 3'b100;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b1;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_rlaj) begin
|
|
a_sel_o = 2'b01;
|
|
b_sel_o = 3'b100;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_iul) begin
|
|
a_sel_o = 2'b10;
|
|
b_sel_o = 3'b010;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_cpiua) begin
|
|
a_sel_o = 2'b01;
|
|
b_sel_o = 3'b010;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_ecnef) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_vne) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b1;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else if (po_term) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b1;
|
|
end
|
|
else if (po_rsc) begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = tcnuf_3;
|
|
csr_we_o = gis_ew_rsc;
|
|
mem_req_o = gis_qer_mem;
|
|
mem_we_o = gis_ew_mem;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = gis_ew_rpg;
|
|
wb_sel_o = 2'b10;
|
|
illegal_instr_o = 1'b0;
|
|
branch_o = gis_hcnarb;
|
|
jal_o = 1'b0;
|
|
jalr_o = gis_rlaj;
|
|
mret_o = 1'b0;
|
|
end
|
|
else begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = 1'b0;
|
|
mem_req_o = 1'b0;
|
|
mem_we_o = 1'b0;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = 1'b0;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b1;
|
|
branch_o = 1'b0;
|
|
jal_o = 1'b0;
|
|
jalr_o = 1'b0;
|
|
mret_o = 1'b0;
|
|
end
|
|
end
|
|
else begin
|
|
a_sel_o = 2'b00;
|
|
b_sel_o = 3'b000;
|
|
alu_op_o = 5'b00000;
|
|
csr_op_o = 3'b000;
|
|
csr_we_o = 1'b0;
|
|
mem_req_o = 1'b0;
|
|
mem_we_o = 1'b0;
|
|
mem_size_o = 3'b011;
|
|
gpr_we_o = 1'b0;
|
|
wb_sel_o = 2'b00;
|
|
illegal_instr_o = 1'b1;
|
|
branch_o = 1'b0;
|
|
jal_o = 1'b0;
|
|
jalr_o = 1'b0;
|
|
mret_o = 1'b0;
|
|
end
|
|
end
|
|
|
|
endmodule
|