@@ -57,9 +57,9 @@ module ibex_compressed_decoder #(
5757 function automatic logic [4 : 0 ] cm_stack_adj_word (input logic [3 : 0 ] rlist,
5858 input logic [1 : 0 ] spimm);
5959 logic [6 : 0 ] tmp;
60- logic [1 : 0 ] _unused ;
60+ logic [1 : 0 ] unused_tmp ;
6161 tmp = cm_stack_adj (.rlist (rlist), .spimm (spimm));
62- _unused = tmp[1 : 0 ];
62+ unused_tmp = tmp[1 : 0 ];
6363 return tmp[6 : 2 ];
6464 endfunction
6565
@@ -79,8 +79,12 @@ module ibex_compressed_decoder #(
7979 function automatic logic [31 : 0 ] cm_push_store_reg (input logic [4 : 0 ] rlist,
8080 input logic [4 : 0 ] sp_offset);
8181 logic [11 : 0 ] neg_offset;
82+ logic signed [11 : 0 ] neg_offset_signed;
8283 logic [31 : 0 ] instr;
83- neg_offset = ~{ 5'b00000 , sp_offset, 2'b00 } + 12'd1 ;
84+ // Compute two's complement on signed variable, then cast back to unsigned
85+ // for the part select operations below.
86+ neg_offset_signed = - signed '({ 5'b00000 , sp_offset, 2'b00 } );
87+ neg_offset = unsigned '(neg_offset_signed);
8488 instr[ 6 : 0 ] /* opcode */ = OPCODE_STORE ;
8589 instr[11 : 7 ] /* offset[4:0] */ = neg_offset[4 : 0 ];
8690 instr[14 : 12 ] /* width */ = 3'b010 ; // 32 bit
@@ -105,15 +109,18 @@ module ibex_compressed_decoder #(
105109 input logic [1 : 0 ] spimm,
106110 input logic decr = 1'b0 );
107111 logic [11 : 0 ] imm;
112+ logic signed [11 : 0 ] imm_signed;
108113 logic [31 : 0 ] instr;
109114 imm[11 : 7 ] = '0 ;
110115 imm[ 6 : 0 ] = cm_stack_adj (.rlist (rlist), .spimm (spimm));
111- if (decr) imm = ~ imm + 12'd1 ;
116+ // Compute two's complement on signed variable, but as it will be used in
117+ // unsigned targets below, it will have to be cast back to unsigned then.
118+ imm_signed = decr ? - signed '(imm) : signed '(imm);
112119 instr[ 6 : 0 ] /* opcode */ = OPCODE_OP_IMM ;
113120 instr[11 : 7 ] /* dest reg */ = 5'd2 ; // x2 (sp / stack pointer)
114121 instr[14 : 12 ] /* funct3 */ = 3'b000 ; // addi
115122 instr[19 : 15 ] /* src reg */ = 5'd2 ; // x2
116- instr[31 : 20 ] /* imm[11:0] */ = imm ;
123+ instr[31 : 20 ] /* imm[11:0] */ = unsigned '(imm_signed) ;
117124 return instr;
118125 endfunction
119126
0 commit comments