如何编写verilog以强制yosys/nextpnr输出手动设计的逻辑块
我想创建一个非常紧凑的并行到串行移位寄存器 我已经手动设计了一个逻辑图块 我希望yosys/nextpnr只在这个磁贴和io引脚之间进行布线 我已经设计了使用yosys原语的代码,但是nextpnr无法将LUT与Carrys融合 代码如下:如何编写verilog以强制yosys/nextpnr输出手动设计的逻辑块,verilog,fpga,yosys,Verilog,Fpga,Yosys,我想创建一个非常紧凑的并行到串行移位寄存器 我已经手动设计了一个逻辑图块 我希望yosys/nextpnr只在这个磁贴和io引脚之间进行布线 我已经设计了使用yosys原语的代码,但是nextpnr无法将LUT与Carrys融合 代码如下: module top ( output PIN_21, PIN_22, PIN_23, PIN_24, USBPU, input CLK, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7, P
module top (
output PIN_21, PIN_22, PIN_23, PIN_24, USBPU,
input CLK, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13
);
wire[12:0] loop;
wire[12:0] carry;
MyCell #(.LUT_INIT('h0F0F)) sRegBorder(loop[0], carry[0], 0, loop[0], PIN_13, 0, 0, CLK);
MyCell #(.LUT_INIT('hFAFA)) sRegA(loop[1], carry[1], loop[0], loop[1], PIN_13, PIN_1, carry[0], CLK);
MyCell #(.LUT_INIT('hFAFA)) sRegB(loop[2], carry[2], loop[1], loop[2], PIN_13, PIN_2, carry[1], CLK);
MyCell #(.LUT_INIT('hFAFA)) sRegC(loop[3], carry[3], loop[2], loop[3], PIN_13, PIN_3, carry[2], CLK);
MyCell #(.LUT_INIT('hFAFA)) sRegD(loop[4], carry[4], loop[3], loop[4], PIN_13, PIN_4, carry[3], CLK);
MyCell #(.LUT_INIT('hFAFA)) sRegE(PIN_24, carry[5], loop[4], PIN_24, PIN_13, PIN_5, carry[4], CLK);
SB_LUT4 #(.LUT_INIT('hFFFF)) sRegFin (PIN_22,0,0,0,carry[5]);
endmodule
module MyCell(output O, CO, input I0, I1, I2, I3, CI, CLK);
parameter [15:0] LUT_INIT = 0;
wire lo;
SB_LUT4 #(.LUT_INIT(LUT_INIT)) lut (lo, I0, I1, I2, I3);
SB_CARRY cr (CO, I1, I2, CI);
SB_DFF dff (O, CLK, lo);
endmodule
预期结果是只有一个具有7个LUT堆栈的磁贴
* PIN_13 should be connected to I2 of the first 6 LUTS.
* PIN_[1-6] should be connected to I3 of the first 6 LUTS, respectivelly.
* every output of the first 6 LUTs should be buffered (DFF) and the buffered output should loop to the I1 of the same LUT.
* every output of the first 5 LUTs shoud also be routed to the I0 of the next LUT in sequence.
* the carry logic should be enabled and flow through the first 6 LUTs and at LUT7 should be captured as an output.
我从yosys那里得到的结果看起来不错,但是nextpnr在整个地方都对LUT进行了屠宰,并为Carry分配了单独的LUT,使用的LUT数量增加了一倍
所以,基本上,如果我知道我想要的输出,至少到一个特定的磁贴配置,我应该写什么作为输入
我尝试在TinyFPGA.BX上编译代码。我相信答案是,您尝试做的事情目前无法完成。我很抱歉这个否定的回答,我也需要紧凑的包装,所以我希望有人能证明我错了 我做了一些调查,下载了最新的
yosys
和nextpnr
(和arachne pnr
),或多或少地复制了你的设计。虽然ICECube2给出了我预期的结果,但yosys/arachne pnr和yosys/nextpnr-ice40都没有成功
/* Just a toy implementation of a shift register, in itself unusable. Written
* to explore how arachne-pnr and nextpnr-ice40 handles SB_CARRY. The design is
* not simulated, hence wrong.
*
* Main results: Neither arachne-pnr nor nextpnr-ice40 are particularly intelligent
* when it comes to SB_CARRY packing.
*
* Details:
*
* When SHOULD_WORK == 1
* =====================
* (a) yosys/arachne-pnr uses too many LUTs: 12
* (b) yosys/next uses too many LUTs: 10
* (c) Lattice ICECube2: 8 (as was expected)
*
* Not satisfied, I tried to use an internal cell definition, ICESTORM_LC.
* Worse and worse...
*
* When SHOULD_WORK == 0
* ======================
* (d) yosys/arachne-pnr uses too many LUTs: 12
* (e) yosys/next uses too many LUTs: 14
*
* Commands used to produce (a) and (d):
* yosys -p "synth_ice40 -blif hardware.blif" -q other.v
* arachne-pnr -d 1k -P vq100 -p other.pcf -o hardware.asc hardware.blif
*
* Commands used to produce (b) and (e):
* yosys -p 'synth_ice40 -top top -json other.json' other.v
* nextpnr-ice40 -v --hx1k --json other.json --pcf other.pcf --asc other.asc
*
* Versions of programs used:
* nextpnr-ice40 -- Next Generation Place and Route (git sha1 b863690). (I pulled the
* code today, 2019.12.05)
* arachne-pnr 0.1+328+0 (git sha1 c40fb22, g++ 5.4.0-6ubuntu1~16.04.12 -O2)
* Yosys 0.9+932 (git sha1 fcce940, clang 3.8.0-2ubuntu4 -fPIC -Os)
*
*/
module top
(
output PIN_22, // Combinatorical, high if shiftreg busy
output PIN_24, // Shift register output.
input CLK,
input PIN_13, // Load
input [5:1] PIN
);
wire [5:0] loop, cy;
assign cy[0] = 1'b0;
`define SHOULD_WORK 1
`ifdef SHOULD_WORK
wire [5:0] cmb_loop;
SB_LUT4 #(.LUT_INIT(16'haaaa)) l_border ( .O(cmb_loop[0]), .I3(1'b0), .I2(1'b0), .I1(1'b0 ), .I0(PIN_13) );
SB_LUT4 #(.LUT_INIT(16'hcaca)) l_sh [4:0] ( .O(cmb_loop[5:1]), .I3(PIN_13), .I2(1'b1), .I1(loop[4:0]), .I0(PIN) );
SB_CARRY l_cy [4:0] ( .CO(cy[5:1]), .CI(cy[4:0]), .I1(1'b1), .I0(loop[4:0]) );
SB_DFF r_sh [5:0] ( .Q(loop), .C(CLK), .D(cmb_loop) );
`else
wire cmbloop0;
SB_LUT4 #(.LUT_INIT(16'haaaa)) l_border ( .O(cmbloop0), .I3(1'b0), .I2(1'b0), .I1(1'b0 ), .I0(PIN_13) );
SB_DFF r_border( .Q(loop[0]), .C(CLK), .D(cmbloop0) );
ICESTORM_LC #(.LUT_INIT(16'hcaca),
.CARRY_ENABLE(1),
.DFF_ENABLE(1))
l_shcyreg [4:0] ( .I0(PIN),
.I1(loop[4:0]),
.I2(1'b1),
.I3(PIN_13),
.CIN(cy[4:0]),
.CLK(CLK),
.O(loop[5:1]),
.COUT(cy[5:1]));
`endif
SB_LUT4 #(.LUT_INIT(16'hff00)) l_empty ( .O(PIN_22), .I3(cy[5]), .I2(1'b0), .I1(1'b0), .I0(1'b0));
assign PIN_24 = loop[5];
endmodule
/* What I hope the code above describe. Should be a total of 7 SB_LUTs,
* and 1 SB_LUT to generate 1'b1
* ___
* |I0 |
* |I1 |---------------------- PIN_22
* |I2 |
* +--|I3_|
* | FF00
* | cy[5]
* /y\
* ||| ___
* PIN_5 -(((-|I0 | _
* +--------+((-|I1 |----| |--- loop[5] --- PIN_24
* | 1 --(+-|I2 | >_|
* +----(---------(--|I3_|
* | | | AACC
* | +---------(---------------+
* |PIN_13 | cy[4] | loop[4]
*
* ::::::::::::::
*
* | | |
* | +---------(---------------+
* | | cy[1] |
* | /y\ |
* | ||| ___ |
* | PIN_1 -(((-|I0 | _ |
* | +--------+((-|I1 |----| |-+ loop[1]
* | | 1 --(+-|I2 | >_|
* +----(---------(--|I3_|
* | | | AACC
* | | 0 cy[0]
* | |
* | +-------------------------+
* | ___ |
* +-----------------|I0 | _ |
* | |I1 |----| |-+ loop[0]
* | |I2 | >_|
* | |I3_|
* | AAAA
* | PIN_13
*/
这是一个非常棘手的问题,它似乎位于第192行附近的
nextpnr/ice40/pack.cc中。很抱歉,我帮不上忙,但也许此输入可用于改进nextpnr-ice40
PIN_22
中的打包,因为sRegFin
的LUT值为16'hFFFF。这可能不是你想要的。(另外,PIN_21
、PIN_23
和USBPU
未连接到任何东西)。我假设您想要PIN_22
显示移位寄存器是否为6'h0,是否正确?是的,sRegFin为16'hFF00,它用于捕获进位并将其作为输出显示。PIN_1
通过PIN_5
连接到SB_LUT4 I3,不向电路提供输入,因为LUT值为16'hfafa,这可能不是您想要的。所描述的PIN_6
不参与代码?因此FAFA想给出这个语义,也许我做得不对。O=I2?I3:I0。即使它不用于lut,但实际上用于进位功能,lut也会忽略该输入。热爱你的asciiart。是的,冰暴将是一个答案。唉:目前,暴风雪被认为是一个内部结构。所以也许在这个假期里,我可以花点时间整理一下行李。ccI希望能抽出时间做些体面的事情;并参与其中(增强pack.cc
)。也有考虑级联LUTS的问题。这是不容易解决的。无论发生什么,我们都会在pack.cc
中看到变化。另外,我还尝试了(*BEL..*)
针对这个特殊问题的放置约束-它对SB_DFF有影响,而不是对SB_LUT4或SB_CARRY有影响。