[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: icarus verilog: IVL_LPM_CMP_EQ not supported by thistarget



I ran the sample file on Icarus Verilog 0.7, got the same result.

After taking a briefly look into the code,  I found there were no any comparators implemented for fpga-lpm. See the following snippet from tgt-fpga/d-lpm.c

const struct device_s d_lpm_edif = {
      lpm_show_header,
      lpm_show_footer,
      0,
      0,
      lpm_logic,
      lpm_show_dff, /* show_dff */
      0,
      0,
      0,
      0, /* show_cmp_gt */
      lpm_show_mux, /* show_mux */
      lpm_show_add, /* show_add */
      lpm_show_add, /* show_sub */
      0, /* show_shiftl */
      0, /* show_shiftr */
      lpm_show_mult, /* show_mult */
      lpm_show_constant /* show_constant */
};

However looking into t-dll.c, you will see LPM comparators are still assigned to objects.

     if (net->pin_AGEB().is_linked()) {
            const Nexus*nex = net->pin_AGEB().nexus();
            obj->type = IVL_LPM_CMP_GE;
                                                                                                                           
            assert(nex->t_cookie());
            obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie();
            nexus_lpm_add(obj->u_.arith.q[0], obj, 0,
                          IVL_DR_STRONG, IVL_DR_STRONG);
                                                                                                                           
      } else if (net->pin_AGB().is_linked()) {
            const Nexus*nex = net->pin_AGB().nexus();
            obj->type = IVL_LPM_CMP_GT;
                                                                                                                           
            assert(nex->t_cookie());
            obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie();
            nexus_lpm_add(obj->u_.arith.q[0], obj, 0,
                          IVL_DR_STRONG, IVL_DR_STRONG);


Cheers,

Ming Deng



Thomas A.D. Riley wrote:
The category of this potential bug is it generates incorrect target code (maybe)

iverilog -o FIRcontroller_1.edif-lpm -parch=lpm -tfpga -Wall -S FIRcontroller_1.v
gives:
fpga.tgt: IVL_LPM_CMP_EQ not supported by this target.
fpga.tgt: IVL_LPM_CMP_EQ not supported by this target.


iverilog -o FIRcontroller_2.edif-lpm -parch=lpm -tfpga -Wall -S  FIRcontroller_2.v
gives no error messages

Comparing the resulting edif netlist from each case suggests to me that FIRcontroller_1.edif-lpm is missing the required gates for the compare.

Although, FIRcontroller_2.v looks friendlier to the compiler,
iverilog -o FIRcontroller_2.edif-virtex -parch=virtex -tfpga -Wall -S  FIRcontroller_2.v
gives
ivl: xilinx.c:671: xilinx_logic: Assertion `ivl_logic_pins(net) <= 5' failed.
while FIRcontroller_1.v is OK with a similar command line.

Both files simulate the same if tested with FIRcontroller_tb.v and behave as expected.

Tom Riley
Kaben Research Inc.
tel:    (613) 826 6649 xtn. 112
fax:    (613) 826 6650
mobile: (613) 797 7774
mobile in Europe : 011 358 40 818 4066
http://www.kabenresearch.com



module FIRcontroller(reset, ss_s, sample, n_state, clock, db64_clk); input reset; // reset input ss_s; input [3:0] sample; input [3:0] n_state; input clock; output db64_clk; reg db64_clk; ///////////////////// // Local Registers // ///////////////////// reg [4:0] state_en; reg [3:0] state_p0; always @(posedge reset or posedge clock) begin if (reset) begin // initialize state_en <= 5'b00000; state_p0 <= 4'b0000; db64_clk <= 1'b0; end // initialize else begin // counting if (state_en == 5'd8) begin db64_clk <= ~db64_clk; end state_en <= state_en+1'b1; if (state_en == 5'b11111) begin if (ss_s) begin // set state and sample (on next clock) state_p0 <= n_state; end // ss_s else begin state_p0 <= state_p0+4'b0001; end end // counting end // initialize end //always endmodule

module FIRcontroller(reset, ss_s, sample, n_state, clock, db64_clk); input reset; // reset input ss_s; input [3:0] sample; input [3:0] n_state; input clock; output db64_clk; reg db64_clk; ///////////////////// // Local Registers // ///////////////////// reg [4:0] state_en; reg [3:0] state_p0; ///////////////// // Local Wires // ///////////////// wire try1 = (state_en == 5'd8); wire try2 = (state_en == 5'b11111); always @(posedge reset or posedge clock) begin if (reset) begin // initialize state_en <= 5'b00000; state_p0 <= 4'b0000; db64_clk <= 1'b0; end // initialize else begin // counting if (try1) begin db64_clk <= ~db64_clk; end state_en <= state_en+1'b1; if (try2) begin if (ss_s) begin // set state and sample (on next clock) state_p0 <= n_state; end // ss_s else begin state_p0 <= state_p0+4'b0001; end end // counting end // initialize end //always endmodule

`include "FIRcontroller_2.v" module FIRcontroller_tb(); reg reset,clk,ss_s; reg [3:0] nstate,sample; initial begin reset = 1'b0; clk = 1'b0; ss_s = 1'b0; nstate = 4'b0100; $display(""); $display(" time p0 en c"); $display(" ----- ---- ----- -"); #6 reset = 1'b1; #5 reset = 1'b0; #5 ss_s = 1'b1; #4 ss_s = 1'b0; #10 $display(""); #3540 ss_s = 1'b1; sample = 4'b0110; #320 ss_s = 1'b0; #5000 $finish; end always begin #8 $display( " %5d %b %b %b", $time, u0.state_p0, u0.state_en, db64_clk ); #1 clk = ~clk; #1 clk = ~clk; end FIRcontroller u0(reset,ss_s,sample,nstate,clk,db64_clk); endmodule