|
@@ -72,6 +72,17 @@
|
|
|
`define PICORV32_V
|
|
|
|
|
|
|
|
|
+function logic [31:0] do_ctz(logic [31:0] rs1);
|
|
|
+ logic [31:0] n = 32'd0;
|
|
|
+ for (int i = 0; i < 32; i++)
|
|
|
+ begin
|
|
|
+ if (rs1[i])
|
|
|
+ break;
|
|
|
+ n++;
|
|
|
+ end
|
|
|
+ do_ctz = n;
|
|
|
+endfunction // do_ctz
|
|
|
+
|
|
|
/***************************************************************
|
|
|
* picorv32
|
|
|
***************************************************************/
|
|
@@ -685,6 +696,7 @@ module picorv32 #(
|
|
|
reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and;
|
|
|
reg instr_csrr, instr_ecall_ebreak;
|
|
|
reg instr_addqxi, instr_addxqi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer;
|
|
|
+ reg instr_ctz;
|
|
|
reg [2:0] instr_funct2;
|
|
|
|
|
|
wire instr_trap;
|
|
@@ -718,7 +730,7 @@ module picorv32 #(
|
|
|
instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw,
|
|
|
instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai,
|
|
|
instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and,
|
|
|
- instr_csrr, instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer};
|
|
|
+ instr_csrr, instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer, instr_ctz};
|
|
|
|
|
|
reg [63:0] new_ascii_instr;
|
|
|
`FORMAL_KEEP reg [63:0] dbg_ascii_instr;
|
|
@@ -777,6 +789,7 @@ module picorv32 #(
|
|
|
if (instr_and) new_ascii_instr = "and";
|
|
|
|
|
|
if (instr_csrr) new_ascii_instr = "csrr";
|
|
|
+ if (instr_ctz) new_ascii_instr = "ctz";
|
|
|
|
|
|
if (instr_addqxi) new_ascii_instr = "addqxi";
|
|
|
if (instr_addxqi) new_ascii_instr = "addxqi";
|
|
@@ -1124,6 +1137,9 @@ module picorv32 #(
|
|
|
instr_or <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b110 && mem_rdata_q[31:25] == 7'b0000000;
|
|
|
instr_and <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b111 && mem_rdata_q[31:25] == 7'b0000000;
|
|
|
|
|
|
+ instr_ctz <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'h30 &&
|
|
|
+ mem_rdata_q[24:20] == 5'h01;
|
|
|
+
|
|
|
instr_csrr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[13:12] != 2'b00);
|
|
|
|
|
|
instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[13:12]) ||
|
|
@@ -1206,7 +1222,18 @@ module picorv32 #(
|
|
|
instr_sra <= 0;
|
|
|
instr_or <= 0;
|
|
|
instr_and <= 0;
|
|
|
+
|
|
|
+ instr_ctz <= 0;
|
|
|
+ instr_csrr <= 0;
|
|
|
+
|
|
|
instr_addqxi <= 0;
|
|
|
+ instr_addxqi <= 0;
|
|
|
+ instr_maskirq <= 0;
|
|
|
+ instr_waitirq <= 0;
|
|
|
+ instr_timer <= 0;
|
|
|
+
|
|
|
+ instr_ecall_ebreak <= 0;
|
|
|
+
|
|
|
end
|
|
|
end
|
|
|
|
|
@@ -1321,6 +1348,8 @@ module picorv32 #(
|
|
|
alu_out = reg_op1 | reg_op2;
|
|
|
instr_andi || instr_and:
|
|
|
alu_out = reg_op1 & reg_op2;
|
|
|
+ instr_ctz:
|
|
|
+ alu_out = do_ctz(reg_op1);
|
|
|
BARREL_SHIFTER && (instr_sll || instr_slli):
|
|
|
alu_out = alu_shl;
|
|
|
BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai):
|