UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor nahdoa
Visitor
3,305 Views
Registered: ‎03-01-2016

Counter variable across two different always blocks

Hi guys, 

 

I am having some trouble with getting a counter variable to work across two different always blocks. This code is part of a much bigger picture. Basically I am trying to keep track of the number of bytes which need to be written from external RAM to external sd card (from volatile to non-volatile memory). In one always block new bytes are marked in a 'dirt table', indicating that these bytes have changed and need to be updated. In the other always block I transverse the dirt table, if a byte is marked I then updated the sdcard with the corresponding byte from my external RAM, I then decrement the byte counter.

 

With my current implementation I need to transverse the entire RAM dirt table to check which bytes need to be updated. My solution works well but I want to speed up the process. So, I would like to keep track of how many bytes need to be updated. If i do this then I can terminate the dirt table search whenever I have written all of the dirty bytes to RAM instead of blindly transverse the entire table even after all of the dirty bytes have been updated.

 

I have tried the implementation below (it is sudo code), however my count variable doesn't seem to be accurate. Is there a better way of keeping track of a variable between two always blocks?

 

input setEdge;
input newbyte;

reg [15:0] numbytes_q, numbytes_d;

always @* begin
    numbytes_d = numbytes_q
    if(newbyte) begin
         numbytes_d = numbytes_q + 1;
    end
end

always @(posedge clk) begin
     if(setEdge) begin
         //send one of the bytes, decrement counter by one.
         numbytes_q <= numbytes_q - 1;
     end else begin
         numbytes_q <= numbytes_d;
     end
end
0 Kudos
4 Replies
Teacher muzaffer
Teacher
3,293 Views
Registered: ‎03-31-2012

Re: Counter variable across two different always blocks

you don't really need two always blocks.

what about:

 

     end else if (newbyte) begin
         numbytes_q <= numbytes_q +1;
     end

 

- 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
Visitor nahdoa
Visitor
3,277 Views
Registered: ‎03-01-2016

Re: Counter variable across two different always blocks

@muzaffer

 

Thanks for the suggestion, but as I mentioned in my original post this problem is part of a much larger code base. The reason for the two always blocks is that one is essentially a state machine running off a 100Mhz input clock signal, the FPGA main clock source. The other always block is triggered by an external clock source, in this case a piece of hardware I am interfacing with. The clocks are not synchronized or the same speeds.

0 Kudos
Teacher muzaffer
Teacher
3,266 Views
Registered: ‎03-31-2012

Re: Counter variable across two different always blocks

>>  The clocks are not synchronized or the same speeds.

 

There is your problem. There is no amount of heartache this won't cause you (said Yoda ;-). You have to find a way to compute all your logic in the same clock. Read about asynchronous clocks and clock domain crossing if you are not familiar with the topic.

- 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
3,254 Views
Registered: ‎01-23-2009

Re: Counter variable across two different always blocks

As always, I start answers to this with the phase "Think Hardware". You are asking for the synthesis tool to create some circuit that changes on the rising edges of two different clocks. What hardware cell that you know of can do this? In an FPGA, the answer is "there is no such thing".

 

For "generic" logic, an FPGA has LUTs (and some other stuff) for combinatorial logic, flip-flops (which have only one clock input) and latches. None of these have two clocks. Therefore, it shouldn't be a surprise to you that the tools are telling you "What you are asking me is impossible" - it's right!

 

So, as @muzaffer said, you absolutely have to find a way of doing this counter on one clock. If the conditions that affect this clock come from different clock domains, then you first must properly cross one of the two conditions from its clock domain to the other one, and do the counter on only one domain.

 

Alternatively, you need to create an architecture that does what you want in a different way. For example, it may be possible to have TWO counters, one on each domain, and then do some kind of comparison between them with proper clock crossing to accomplish what you want - this is, for example, how the read and write pointers of a FIFO operate...

 

Avrum

 

Tags (1)
0 Kudos