Forum Discussion
Data corrupted, any problem with VHDL codes
HI everyone.
I just have a quick question to ask. When we use the LOOP in VHDL, is there any chances that the number of times the LOOP is repeated affects the data, say, in the following piece of code, the code "content(i) <= content(i+1)" is repeated 65 times (content is an array of 8bit number), and the data I get at the output of the Modules (dataout[7:0]) is corrupted at some points: -- ram.vhd library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity RAM is generic ( bits: integer := 8; words: integer:= 66); port (clk_in: in std_logic; clk_out: in std_logic; we: in std_logic; re: in std_logic; reset: in std_logic; datain: in std_logic_vector(bits - 1 downto 0); dataout: out std_logic_vector(bits - 1 downto 0) ); end RAM; architecture beh of RAM is signal readp: integer range 0 to words; type table is array (0 to words - 1) of std_logic_vector(bits-1 downto 0); signal content: table :=(others => "10000000"); begin process(reset,clk_in, we) begin if (reset = '1') then content <= (others => "10000000"); elsif (clk_in'event and clk_in = '1') then if (we = '1') then for i in 0 to words - 2 loop content(i) <= content(i+1); --***could it be this line? *** end loop; content(words - 1) <= datain; end if; end if; end process; process(clk_out, re) begin if (clk_out'event and clk_out = '1') then if(re = '1') then dataout <= content(readp); end if; end if; end process; process(clk_out, re, reset) begin if (reset = '1') then readp <= 0; elsif (clk_out'event and clk_out = '0') then if(re = '1') then readp <= readp + 1; if(readp = words - 1) then readp <= 0; end if; end if; end if; end process; end beh; Any suggestion would be greatlly appreciated. Cheers. J.13 Replies
- Altera_Forum
Honored Contributor
--- Quote Start --- YEAHHHH, EXCELLENT, I've just tried to put a CLKINT (which make the clock line global) and the problem disappears. I have had some problems which were solved by using a CLKINT before, but didn't know why it helped. Now turns out it's all about the clock skew problem. Yeah, it is a correlator that I'm designing, I tried 2 methods, the other was to use a series of Shift register and Multipliers, but no way it's fit in the chip I was given. The MAC method involves so many problems, it's a nightmare. Could you think of any other methods? J. --- Quote End --- Glad to help! Whilst I have designed a number of correlators ours always have to run flat out so we sacrifice resources to get speed (and use quite large FPGAs). The current one has 140 parallel accumulators and recirculates the complex PN sequence in a 2bit wide 80 bit long shift register (rather than circulating the 24 bit wide data). I've also implemented the same correlator as a Matched Data Filter arrangement - they take more or less the same resources. In your case you could maybe reduce the resource usage by changing from using a shift register to using a Circular buffer which would more easily map into a RAM (assuming your Actel has RAMs). The VHDL would be a little bit more complex but the synthesised logic would be much smaller. Mark. - Altera_Forum
Honored Contributor
Appreciate your help Mark! And the others'
Jimmy - Altera_Forum
Honored Contributor
YEAHHHH, EXCELLENT, I've just tried to put a CLKINT (which make the clock line global) and the problem disappears. I have had some problems which were solved by using a CLKINT before, but didn't know why it helped. Now turns out it's all about the clock skew problem.
Yeah, it is a correlator that I'm designing, I tried 2 methods, the other was to use a series of Shift register and Multipliers, but no way it's fit in the chip I was given. The MAC method involves so many problems, it's a nightmare. Could you think of any other methods? J. - Altera_Forum
Honored Contributor
Ahhh. You didn't use the Global clock! In that case I definitely think you have a clock skew problem, basicaly the data from one latch is bing clocked out in advance of the data to the next latch being clocked in - it's a common problem with large shift registers (I used Actel devices nearly 20 years ago and experienced same) but using a Global clock rather than normal routing should cure it as the skew over the global clock will be much much less than if you've used local routing for the clock.
I assumed it was a correlator you were designing, couldn't think of any other reason for this arrangement. - Altera_Forum
Honored Contributor
--- Quote Start --- Normally I would agree, but if you look at his doc5 (granted not that easy as it RARed) you'll see that clk_in and clk_out are related and mutually exclusive - basically he is clocking in data to a bloody great shift register - then reading out the whole shift register (for some reason) and then clocking in another word. So metastability wise it shouldn't be an issue but as my previous post mentions he has a clock skew/timing issue one one wire! --- Quote End --- Thanks Mark, yeah, as you said, the CLK_IN and CLK_OUT are related to each other, 66 CLK_OUT pulses are covered by 1 CLK_OUT, (in my test, the Clocks were controlled by a microprocessor). --- Quote Start --- Well you can see by the way the error propogates through to subsequent addresses that the error occurs at the input phase (in the shift register) and it is bit 5 (16) that is causing problems - to me it looks like your enormous shift register has a timing problem (posibly due to clock skew) on this one bit between those two elements. Do you get any timing warning from the compiler? Did you use the proper global clock lines for the CLK_IN to keep skew to a minimum? Have you defined any timing constraints? --- Quote End --- Yeah, I think the problem arised at the input phase, which consists of writing the data into content(words - 1) and a series of shifting process. But if you plot a graph of the last column (where the data was first written in --> fine), you will see it is likely the shifting process that cause the error. I don't have any timing warning from the compiler and no global clock lines for the CLK_IN has been used yet (will give it a go)... and no time constraints was defined... --- Quote Start --- So looks like a redesign is the only way to go! --- Quote End --- Thanks vernmid for your suggestion, actually, I'm designing a hardware correlator using a MAC circuit. Wish I could change the design, however the circuit was a given and the FPGA chip doesn't have enough resource for me to drive the design to other directions. Thanks everyone, for your contribution. - Altera_Forum
Honored Contributor
--- Quote Start --- There is a chance, but as the other people have said, if the in_clock and out_clock are unrelated then this design will now work whatever the technology used. --- Quote End --- Normally I would agree, but if you look at his doc5 (granted not that easy as it RARed) you'll see that clk_in and clk_out are related and mutually exclusive - basically he is clocking in data to a bloody great shift register - then reading out the whole shift register (for some reason) and then clocking in another word. So metastability wise it shouldn't be an issue but as my previous post mentions he has a clock skew/timing issue one one wire! - Altera_Forum
Honored Contributor
--- Quote Start --- Actually, I used an Actel FPGA (which I don't like but company does) for this design, not Altera. Is there any chances the way the the logic elements and the net were placed and routed inside the chip corrupted the data? --- Quote End --- There is a chance, but as the other people have said, if the in_clock and out_clock are unrelated then this design will now work whatever the technology used. Imagine the Content(0) word. Due to difference in routing delays for each bit, each bit will change at a slightly different delay after input clock rises. Now imagine you try and latch the output using output clock. Depending on the relationship of the input and output clock edges at this instant it is possible that you will see some of the bits in the word as the new value and some as the previous value. Hence corrupt data! This comment ignores the crucial but unpleasant effects of metastability whereby you violate setup/hold times of flip-flops by changing the input data using a different clock to that latching the data. Also causing corrupt data. So looks like a redesign is the only way to go! - Altera_Forum
Honored Contributor
Well you can see by the way the error propogates through to subsequent addresses that the error occurs at the input phase (in the shift register) and it is bit 5 (16) that is causing problems - to me it looks like your enormous shift register has a timing problem (posibly due to clock skew) on this one bit between those two elements.
Do you get any timing warning from the compiler? Did you use the proper global clock lines for the CLK_IN to keep skew to a minimum? Have you defined any timing constraints? Your spreadsheet and your doc6 do not seem to match up by the way.One shows the error occuring between elements 57 and 56 of the shift register whilst doc6 implies it is elements 63 and 62. Mark. - Altera_Forum
Honored Contributor
Actually, I used an Actel FPGA (which I don't like but company does) for this design, not Altera. Is there any chances the way the the logic elements and the net were placed and routed inside the chip corrupted the data?
- Altera_Forum
Honored Contributor
Thank you for having a look at my post.
Following is the link to some illustration for my design. datacorrupted.rar (http://www.filefactory.com/file/a01448d/n/datacorrupted_rar) (scroll down to option2, click on the link Download With FileFactory Basic) doc5.pdf is the clk_in and clk_out waveform. doc6.pdf is how I want the output to be. doc7.xls is the real data I captured (after transfering the output to a Microprocessor and have it printed on screen). As you can see, at column BF, some of the data is corrupted (one bit changes) making the waveform change dramatically (you can plot a graph of column BF and BE to see the difference). Please note that the clocking was control externally by the microprocessor which is much simpler than internally. The 99 points of data were stored in a FIFO I could have used a built-in RAM (with 99 points stored from address 0 to 98) and ignore the VHDL RAM for this design, but doing this will result in a really complicated addressing system. Any suggestion after having a look at the diagram and data would be really appreciated. Thank you J