mirror of https://github.com/YosysHQ/yosys.git
Fix offset in splitcells
This commit is contained in:
parent
ed11f4c135
commit
300c64773b
|
|
@ -147,6 +147,19 @@ struct SplitcellsWorker
|
||||||
if (GetSize(outsig) <= 1) return 0;
|
if (GetSize(outsig) <= 1) return 0;
|
||||||
int width = GetSize(outsig);
|
int width = GetSize(outsig);
|
||||||
|
|
||||||
|
// Compute user-facing bit index from the wire connected to Q
|
||||||
|
SigSpec raw_q = cell->getPort(ID::Q);
|
||||||
|
auto user_index = [&](int idx) -> int {
|
||||||
|
if (idx < GetSize(raw_q) && raw_q[idx].is_wire()) {
|
||||||
|
Wire *w = raw_q[idx].wire;
|
||||||
|
if (w->upto)
|
||||||
|
return w->start_offset + w->width - 1 - raw_q[idx].offset;
|
||||||
|
else
|
||||||
|
return w->start_offset + raw_q[idx].offset;
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<int> slices;
|
std::vector<int> slices;
|
||||||
slices.push_back(0);
|
slices.push_back(0);
|
||||||
|
|
||||||
|
|
@ -168,6 +181,9 @@ struct SplitcellsWorker
|
||||||
{
|
{
|
||||||
int slice_msb = slices[i]-1;
|
int slice_msb = slices[i]-1;
|
||||||
int slice_lsb = slices[i-1];
|
int slice_lsb = slices[i-1];
|
||||||
|
int name_lsb = user_index(slice_lsb);
|
||||||
|
int name_msb = user_index(slice_msb);
|
||||||
|
if (name_lsb > name_msb) std::swap(name_lsb, name_msb);
|
||||||
|
|
||||||
std::string base_name = cell->name.str();
|
std::string base_name = cell->name.str();
|
||||||
IdString slice_name;
|
IdString slice_name;
|
||||||
|
|
@ -178,11 +194,11 @@ struct SplitcellsWorker
|
||||||
base_name = base_name.substr(0, bracket_pos);
|
base_name = base_name.substr(0, bracket_pos);
|
||||||
}
|
}
|
||||||
slice_name = module->uniquify(base_name + stringf(
|
slice_name = module->uniquify(base_name + stringf(
|
||||||
"%c%d%c", format[0], slice_lsb, format[1]));
|
"%c%d%c", format[0], name_lsb, format[1]));
|
||||||
} else {
|
} else {
|
||||||
slice_name = module->uniquify(base_name + (slice_msb == slice_lsb ?
|
slice_name = module->uniquify(base_name + (name_msb == name_lsb ?
|
||||||
stringf("%c%d%c", format[0], slice_lsb, format[1]) :
|
stringf("%c%d%c", format[0], name_lsb, format[1]) :
|
||||||
stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
|
stringf("%c%d%c%d%c", format[0], name_msb, format[2], name_lsb, format[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
Cell *slice = module->addCell(slice_name, cell);
|
Cell *slice = module->addCell(slice_name, cell);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
# Test 1: Basic splitcells blast on a zero-base register [5:0]
|
||||||
|
# Cell names should use indices 0..5
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module test_zero_base (
|
||||||
|
input clk,
|
||||||
|
input [5:0] d,
|
||||||
|
output reg [5:0] q
|
||||||
|
);
|
||||||
|
always @(posedge clk) q <= d;
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
proc
|
||||||
|
splitcells -blast -format []:
|
||||||
|
|
||||||
|
select -assert-count 6 t:$dff
|
||||||
|
select -assert-count 1 c:*[0]
|
||||||
|
select -assert-count 1 c:*[5]
|
||||||
|
select -assert-none c:*[6]
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
# Test 2: splitcells blast on a non-zero base register [22:17]
|
||||||
|
# Cell names must use user-facing indices 17..22, not 0..5
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module test_nonzero_base (
|
||||||
|
input clk,
|
||||||
|
input [22:17] d,
|
||||||
|
output reg [22:17] q
|
||||||
|
);
|
||||||
|
always @(posedge clk) q <= d;
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
proc
|
||||||
|
splitcells -blast -format []:
|
||||||
|
|
||||||
|
select -assert-count 6 t:$dff
|
||||||
|
select -assert-count 1 c:*[17]
|
||||||
|
select -assert-count 1 c:*[18]
|
||||||
|
select -assert-count 1 c:*[19]
|
||||||
|
select -assert-count 1 c:*[20]
|
||||||
|
select -assert-count 1 c:*[21]
|
||||||
|
select -assert-count 1 c:*[22]
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
# Test 3: splitcells blast with offset=1 register [8:1]
|
||||||
|
# Cell names should use indices 1..8, not 0..7
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module test_offset_one (
|
||||||
|
input clk,
|
||||||
|
input [8:1] d,
|
||||||
|
output reg [8:1] q
|
||||||
|
);
|
||||||
|
always @(posedge clk) q <= d;
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
proc
|
||||||
|
splitcells -blast -format []:
|
||||||
|
|
||||||
|
select -assert-count 8 t:$dff
|
||||||
|
select -assert-count 1 c:*[1]
|
||||||
|
select -assert-count 1 c:*[8]
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
# Test 4: splitcells non-blast with non-zero base and divergent fanout
|
||||||
|
# Slice range names should use user-facing indices (e.g. [22:20], [19:17])
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module test_nonblast_nonzero (
|
||||||
|
input clk,
|
||||||
|
input [22:17] d,
|
||||||
|
output reg [22:17] q,
|
||||||
|
output [2:0] lo,
|
||||||
|
output [2:0] hi
|
||||||
|
);
|
||||||
|
always @(posedge clk) q <= d;
|
||||||
|
assign lo = q[19:17];
|
||||||
|
assign hi = q[22:20];
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
proc
|
||||||
|
splitcells -format []:
|
||||||
|
|
||||||
|
select -assert-count 2 t:$dff
|
||||||
|
select -assert-count 1 c:*[19:17]
|
||||||
|
select -assert-count 1 c:*[22:20]
|
||||||
Loading…
Reference in New Issue