cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
saajan.chana
Visitor
Visitor
12,401 Views
Registered: ‎11-24-2009

Xst:899 trying to infer FDCP

Jump to solution

Hi,

 

I'm trying to infer a flipflop with both asynchronous clear and preset with the following behaviour:


FDCP ff (.C(clk), .D(1'b1), .PRE(pre), .CLR(clr), .Q(q));

Here's the code I'm using:

 

module fdcp_wrapper(clk, pre, clr, q);

input clk;
input pre;
input clr;
output reg q;

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr == 1'b1)
    q <= 1'b0;
  else if(pre == 1'b1)
    q <= 1'b1;
  else
    q <= 1'b1;
end

endmodule

 

XST informs me that "The logic for <q> does not match a known FF or Latch template."   I thought maybe having both preset and clear on a single flipflop was not supported - except that it synthesizes fine if I swap the the clr and pre priorities around!  Of course, in this case it adds extra prioritisation logic on to the CLR input.  So, what am I missing?  This is not a massive problem, just a bit of a mystery.  Using ISE 11.1.

 

Cheers,

 

Saajan.

 

0 Kudos
1 Solution

Accepted Solutions
gszakacs
Instructor
Instructor
14,530 Views
Registered: ‎08-14-2007

It's one of the shortcomings of Verilog that you can't describe a flip-flop with a clock

and preset and clear in one always block.  If you look at the simulation model for FDCP

you'll find it has more than one block (although it also has an extra block for GSR behavior

it still needs at least two blocks just for the reset/preset and clock).

 

What you wrote:

 

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr)
    q <= 1'b0;
  else if(pre)
    q <= 1'b1;
  else
    q <= d;
end

 

doesn't handle the case of releasing clr or pre while the other signal is active.

 

I'm afraid your best work-around is to instantiate the flip-flop.

 

Regards,

Gabor

 

PS There was a lengthy thread about this on comp.lang.verilog

 

-- Gabor

View solution in original post

0 Kudos
5 Replies
bassman59
Historian
Historian
12,396 Views
Registered: ‎02-25-2008

Your default case (after the last else) assigns q <= 1'b1; and I would guess that you really want q <= d;

 

 

----------------------------Yes, I do this for a living.
0 Kudos
saajan.chana
Visitor
Visitor
12,394 Views
Registered: ‎11-24-2009

Hi bassman,

 

Bizarrely enough, q <= 1'b1 is correct in this case (it's reproducing the behaviour of some legacy hardware).  I can achieve the behaviour I want by directly instantiating an FDCP as at the top of my previous post but apparently not by inferring it.

 

Although, after reading your post, I tried this:

 

wire d;
assign d = 1'b1;

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr)
    q <= 1'b0;
  else if(pre)
    q <= 1'b1;
  else
    q <= d;
end

 

which works perfectly.  Though this seems like a somewhat dubious workaround!  Is this something which I should expect to work?  It's certainly unusual, but doesn't seem that unlikely!

 

Cheers,

 

Saajan.

 

0 Kudos
gszakacs
Instructor
Instructor
14,531 Views
Registered: ‎08-14-2007

It's one of the shortcomings of Verilog that you can't describe a flip-flop with a clock

and preset and clear in one always block.  If you look at the simulation model for FDCP

you'll find it has more than one block (although it also has an extra block for GSR behavior

it still needs at least two blocks just for the reset/preset and clock).

 

What you wrote:

 

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr)
    q <= 1'b0;
  else if(pre)
    q <= 1'b1;
  else
    q <= d;
end

 

doesn't handle the case of releasing clr or pre while the other signal is active.

 

I'm afraid your best work-around is to instantiate the flip-flop.

 

Regards,

Gabor

 

PS There was a lengthy thread about this on comp.lang.verilog

 

-- Gabor

View solution in original post

0 Kudos
ywu
Xilinx Employee
Xilinx Employee
12,336 Views
Registered: ‎11-28-2007

 I'm probably missing something about needing two always blocks to model FDCP. Doesn't the code snippet below correctly model an FDCP (although it may not work to infer an FDCP)?

 

wire pre_int = ~clr & pre;
always @(posedge clk or posedge pre_int or posedge clr)
begin
  if (clr == 1'b1)
    q <= 1'b0;
  else if (pre_int == 1'b1)
    q <= 1'b1;
  else
    q <= 1'b;
end

 

As a side note, Virtex6 and Spartan6 don't have FFs with both set and reset, so FDCP will not be able to directly map to an FF. Try avoiding using it if possible.

 

Cheers,

Jim


gszakacs wrote:

It's one of the shortcomings of Verilog that you can't describe a flip-flop with a clock

and preset and clear in one always block.  If you look at the simulation model for FDCP

you'll find it has more than one block (although it also has an extra block for GSR behavior

it still needs at least two blocks just for the reset/preset and clock).

 

What you wrote:

 

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr)
    q <= 1'b0;
  else if(pre)
    q <= 1'b1;
  else
    q <= d;
end

 

doesn't handle the case of releasing clr or pre while the other signal is active.

 

I'm afraid your best work-around is to instantiate the flip-flop.

 

Regards,

Gabor

 

PS There was a lengthy thread about this on comp.lang.verilog

 


 

 

Cheers,
Jim
0 Kudos
gszakacs
Instructor
Instructor
12,334 Views
Registered: ‎08-14-2007

The problem shows up if you assert both pre and clr at the same time and then

release one of them:

 

always @(posedge clk or posedge pre or posedge clr)
begin
  if(clr)
    q <= 1'b0;
  else if(pre)
    q <= 1'b1;
  else
    q <= d;
end

 

The above code only triggers (for simulation) on positive (assertion) edge of

pre or clr.  If you're nice and never assert both simultaneously this works

properly.  If you assert both, clr wins over pre and the output goes to 0.

Then if you de-assert clr while leaving pre asserted, a real flip-flop goes

high while the simulation remains low because there is no rising edge

on pre.

 

Your intermediate term pre_int seems to take care of this case by adding

a rising edge to pre when clr is de-asserted.  It's likely that XST would

actually add the gate to the preset input rather than understanding

that it's there to add a trigger condition to the block.  Probably worth a try.

 

The standard simulation modules usually look like:

 

always @ (clr or pre)

  if (clr) q = 0;

  else if (pre) q = 1;

 

always @ (posedge clk)

  if (!clr & !pre) q <= d;

 

This is the equivalent of the standard VHDL template:

 

process (clk, clr, pre)

  if (clr = '1') then q <= '0';

  elsif (pre = '1') then q <= '1';

  else if rising_edge(clk) q <= d;

  end if;

end process;

 

(might be some syntax errors there, my VHDL is a bit rusty).

The thing you get easily with VHDL but not (synthesizable)

Verilog is the separation of the rising edge event from the

process sensitivity list.

 

Regards,

Gabor

-- Gabor
0 Kudos