mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-07 06:33:24 +00:00
Merge pull request #5148 from georgerennie/george/convertible_to_int_fix
Fix convertible_to_int handling of 32 bit unsigned ints with MSB set.
This commit is contained in:
commit
3ef4c91c31
2 changed files with 65 additions and 13 deletions
|
@ -383,7 +383,23 @@ int RTLIL::Const::as_int(bool is_signed) const
|
||||||
bool RTLIL::Const::convertible_to_int(bool is_signed) const
|
bool RTLIL::Const::convertible_to_int(bool is_signed) const
|
||||||
{
|
{
|
||||||
auto size = get_min_size(is_signed);
|
auto size = get_min_size(is_signed);
|
||||||
return (size > 0 && size <= 32);
|
|
||||||
|
if (size <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If it fits in 31 bits it is definitely convertible
|
||||||
|
if (size <= 31)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If it fits in 32 bits, it is convertible if signed or if unsigned and the
|
||||||
|
// leading bit is not 1
|
||||||
|
if (size == 32) {
|
||||||
|
if (is_signed)
|
||||||
|
return true;
|
||||||
|
return get_bits().at(31) != State::S1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> RTLIL::Const::try_as_int(bool is_signed) const
|
std::optional<int> RTLIL::Const::try_as_int(bool is_signed) const
|
||||||
|
@ -439,18 +455,7 @@ void RTLIL::Const::compress(bool is_signed)
|
||||||
|
|
||||||
std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
|
std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
|
||||||
{
|
{
|
||||||
auto size = get_min_size(is_signed);
|
return try_as_int(is_signed);
|
||||||
if(size == 0 || size > 32)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
int32_t ret = 0;
|
|
||||||
for (auto i = 0; i < size && i < 32; i++)
|
|
||||||
if ((*this)[i] == State::S1)
|
|
||||||
ret |= 1 << i;
|
|
||||||
if (is_signed && (*this)[size-1] == State::S1)
|
|
||||||
for (auto i = size; i < 32; i++)
|
|
||||||
ret |= 1 << i;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RTLIL::Const::as_string(const char* any) const
|
std::string RTLIL::Const::as_string(const char* any) const
|
||||||
|
|
|
@ -111,3 +111,50 @@ select -assert-none t:$shr
|
||||||
select -assert-none t:$sshl
|
select -assert-none t:$sshl
|
||||||
select -assert-none t:$sshr
|
select -assert-none t:$sshr
|
||||||
select -assert-none t:$shiftx
|
select -assert-none t:$shiftx
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module top (
|
||||||
|
input wire [3:0] in,
|
||||||
|
output wire [7:0] shl,
|
||||||
|
output wire [7:0] shr,
|
||||||
|
output wire [7:0] sshl,
|
||||||
|
output wire [7:0] sshr,
|
||||||
|
output wire [7:0] shiftx,
|
||||||
|
|
||||||
|
output wire [7:0] shl_s,
|
||||||
|
output wire [7:0] shr_s,
|
||||||
|
output wire [7:0] sshl_s,
|
||||||
|
output wire [7:0] sshr_s,
|
||||||
|
output wire [7:0] shiftx_s,
|
||||||
|
);
|
||||||
|
assign shl = in << 32'hffffffff;
|
||||||
|
assign shr = in >> 32'hffffffff;
|
||||||
|
assign sshl = in <<< 32'hffffffff;
|
||||||
|
assign sshr = in >>> 32'hffffffff;
|
||||||
|
assign shiftx = in[32'hffffffff +: 8];
|
||||||
|
|
||||||
|
wire signed [31:0] shamt = 32'hffffffff;
|
||||||
|
assign shl_s = in << shamt;
|
||||||
|
assign shr_s = in >> shamt;
|
||||||
|
assign sshl_s = in <<< shamt;
|
||||||
|
assign sshr_s = in >>> shamt;
|
||||||
|
assign shiftx_s = in[shamt +: 8];
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
|
||||||
|
select -assert-count 2 t:$shl
|
||||||
|
select -assert-count 2 t:$shr
|
||||||
|
select -assert-count 2 t:$sshl
|
||||||
|
select -assert-count 2 t:$sshr
|
||||||
|
select -assert-count 1 t:$shiftx
|
||||||
|
|
||||||
|
equiv_opt opt_expr
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
select -assert-none t:$shl
|
||||||
|
select -assert-none t:$shr
|
||||||
|
select -assert-none t:$sshl
|
||||||
|
select -assert-none t:$sshr
|
||||||
|
select -assert-none t:$shiftx
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue