cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
4,741 Views
Registered: ‎01-19-2009

Broken Xst netlist when byte-wide BRAM write enable is connected to FSM

Hi,

 

On Spartan-6, synthesizing the source code below with ISE 14.7 results in the block RAM not being connected properly.  In the generated netlist, an obvious effect of the bug is that the WE and data input ports of the block RAM are grounded. It seems to manifest itself when a block RAM uses byte-wide write enable, and that signal is driven by a state machine.

Sebastien

module memtest(
	input clk,
	input [9:0] adr,
	input [31:0] dat_w,
	output [31:0] dat_r,
	input wex
);

reg [3:0] we;
reg [31:0] mem[0:1023];
reg [9:0] memadr_r;
always @(posedge clk) begin
	if (we[0])
		mem[adr][7:0] <= dat_w[7:0];
	if (we[1])
		mem[adr][15:8] <= dat_w[15:8];
	if (we[2])
		mem[adr][23:16] <= dat_w[23:16];
	if (we[3])
		mem[adr][31:24] <= dat_w[31:24];
	memadr_r <= adr;
end

assign dat_r = mem[memadr_r];

reg [1:0] state;
reg [1:0] next_state;
always @(posedge clk) state <= next_state;

always @(*) begin
	we <= 0;
	next_state <= state;
	case(state)
		2'd0: if(wex) next_state <= 1;
		2'd1: next_state <= 2;
		2'd2: begin
			we <= 15;
			next_state <= 0;
		end
	endcase
end

endmodule
0 Kudos
5 Replies
Highlighted
Teacher
Teacher
4,735 Views
Registered: ‎03-31-2012

Re: Broken Xst netlist when byte-wide BRAM write enable is connected to FSM

Did you simulate your code? Make sure that it does what you want before synthesis.
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Highlighted
Historian
Historian
4,721 Views
Registered: ‎02-25-2008

Re: Broken Xst netlist when byte-wide BRAM write enable is connected to FSM


@sbourdeauducq wrote:

 

 

always @(*) begin
	we <= 0;
	next_state <= state;
	case(state)
		2'd0: if(wex) next_state <= 1;
		2'd1: next_state <= 2;
		2'd2: begin
			we <= 15;
			next_state <= 0;
		end
	endcase
end

endmodule

TWO-PROCESS STATE MACHINE FAIL.

Try recoding it as a single synchronous always block.

 

I think the "default assignments" to we and next_state (with the expectation that the signal might be overridden in a decoded state) don't work in a combinatorial always block. It forms an infinite loop.

----------------------------Yes, I do this for a living.
0 Kudos
Highlighted
Teacher
Teacher
4,717 Views
Registered: ‎03-31-2012

Re: Broken Xst netlist when byte-wide BRAM write enable is connected to FSM

Not really; for an infinite loop to happen, the same signal should be on the left and right hand side of multiple assignments. In this case we and next_state are only on the LHS and they have no other combinational path to themselves. I don't think that is his problem. From other posts it seems XST has a problem with byte enabled block ram extraction.
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Highlighted
Scholar
Scholar
4,709 Views
Registered: ‎09-16-2009

Re: Broken Xst netlist when byte-wide BRAM write enable is connected to FSM

 

There's nothing wrong with that state machine style.  Other than the non-blocking statements in the combinational block.  I know many feel strongly on this, and for newbies I suggest the single process state machine style.  But if you know what you're doing this two process style is fine (and has some advantages IMHO).

 

You cannot form an infinite loop in a single always block like this.  An always block CANNOT trigger itself.  Part of the verilog stratified event queue.

 

As to the OP's problem...

 

Early on in (ISE 12.2 I think), we noticed similar problems with RAM inference.  The byte enables didn't always work properly.  We tried breaking it down to a simple testcase for Xilinx to look at, and the results were inconsistent - we couldn't repeat the failure with a testcase.

 

So we worked around the issue by not inferring the Byte enables - instead we just inferred (4) parallel 8-bit RAMs, with seperate Write enables. This effectively decreases your RAM granularity you're inferring (4) Byte-wide memories.  But it works...

 

I'd not thought that the problem was related to a state machine driving some of the RAM control signals.  That might be a good hint that we didn't think of.  If you can replicate the problem in a small testcase, I'd submit the problem to Xilinx.

 

Regards,

 

Mark

0 Kudos
Highlighted
Guide
Guide
4,704 Views
Registered: ‎01-23-2009

Re: Broken Xst netlist when byte-wide BRAM write enable is connected to FSM

(I know this is no longer on the RAM topic, but the state machine topic)

 

An always block CANNOT trigger itself.

 

It is true that an always block cannot directly trigger itself, but it can do so indirectly. If (as the OP did in this example) you use non-blocking assignments in your always block, then the non-blocking assignment can re-trigger the same always block.

 

The reason a blocking assignment cannot re-trigger the same block is that the blocking assignment is done immediately; thus, when the signal makes its state change, the always block is not "blocked" waiting for the always @* event to occur. When the block ends, and returns to waiting for the always @*, the variable is already at its new value, and hence the block won't retrigger.

 

However, a non-blocking assignment is defferred to the NBA portion of the stratified queue, which is executed after all active events. At that time, all  "always" blocks that have no internal timing control (no #, @ or wait statements) are back at the always @(*) or always @(posedge clk) statement - waiting for an event to re-trigger them. Thus, when the NBA completes, the block can re-trigger.

 

So

 

always @(a)

  a = !a;

 

Will not (on its own) create an infinite loop, but

 

always @(a)

  a <= !a;

 

will.

 

To that point - you should NEVER use a non-blocking assignment inside an always @(*) block - you should use blocking assignments.

 

Avrum

0 Kudos