- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm facing a strange problem with one of the FIFO reads (FIFO used for transferring data from one clock domain to another) - The problem is that, the very first datum is NOT getting written into the memory. I've captured the FIFO interface signals using SignalTap and attached the same for your reference. You may please check the attached waveform fail_dsp_18Aug.jpg, the data 0x11e00de is not coming at the rd_data, though the pointers are incremented properly. Kindly compare this waveform with pass_dsp_18Aug.jpg. The problem is not present always on the board. Every one out of five attempts results in this behavior randomly. In the RTL the memory element in the FIFO is coded as a two dimensional array reg[36:0] mem[3:0]; The write and read are controlled as always @(posedge wr_clk) begin if (wr_en) begin mem[wr_ptr] <= wr_data; end end assign rd_data = mem[rd_ptr]; The write and read pointers are taken care separately. Logical errors are not doubted as the same async fifo is silicon proven. In FPGA implementation report, it looks like the memory is implemented using M9K. Info: Found 1 design units, including 1 entities, in source file db/altsyncram_lth1.tdf Info: Found entity 1: altsyncram_lth1 Info: Elaborated megafunction instantiation "ONU_CORE:U_ONU_CORE|VOIP_TOP:U_VOIP_TOP|vip1000_voip:U_VIP1000_VOIP|pcp:u_pcp|pcpcore:pcpcore|pcp_mainmem_if:pcp_mainmem_if|pcp_mainmem_sync:pcp_mainmem_sync|async_fifo:m2b_fifo|altsyncram:mem_rtl_1" Info: Instantiated megafunction "ONU_CORE:U_ONU_CORE|VOIP_TOP:U_VOIP_TOP|vip1000_voip:U_VIP1000_VOIP|pcp:u_pcp|pcpcore:pcpcore|pcp_mainmem_if:pcp_mainmem_if|pcp_mainmem_sync:pcp_mainmem_sync|async_fifo:m2b_fifo|altsyncram:mem_rtl_1" with the following parameter: Info: Parameter "OPERATION_MODE" = "DUAL_PORT" Info: Parameter "WIDTH_A" = "37" Info: Parameter "WIDTHAD_A" = "2" Info: Parameter "NUMWORDS_A" = "4" Info: Parameter "WIDTH_B" = "37" Info: Parameter "WIDTHAD_B" = "2" Info: Parameter "NUMWORDS_B" = "4" Info: Parameter "ADDRESS_ACLR_A" = "NONE" Info: Parameter "OUTDATA_REG_B" = "UNREGISTERED" Info: Parameter "ADDRESS_ACLR_B" = "NONE" Info: Parameter "OUTDATA_ACLR_B" = "NONE" Info: Parameter "ADDRESS_REG_B" = "CLOCK1" Info: Parameter "INDATA_ACLR_A" = "NONE" Info: Parameter "WRCONTROL_ACLR_A" = "NONE" I'm wondering if there is anything wrong in the implementation. Any help in solving this issue is highly appreciated. Regards, NishanthLink Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There isn't any read clock on your waveforms, but I'm guessing that the read clock is twice as fast as the write clock?
It could be a timing problem. Is your design properly constrained and does it meet timing requirements?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Yes. The read clock is twice as fast as write clock. The design is properly constrained and there are no violations reported by the tool. Is there any restriction with the memory unit for the skew requirement for write and read clocks? If so, then is there any possibility of write getting blocked, when skew violation occur?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As long as there is no timing violation reported there shouldn't be any problem. AFAIK there can be any skew between the two clocks.
Are you sure that you use the read clock correctly in your code? The read operation should be in analways @(posedge rd_clk)
block, which doesn't show on your first post. Now that I think about it, your waveforms are consistent with a read only done on the rising edge of wr_clk.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Thanks for the quick reply.
I have the read logic as assign rd_data = mem[rd_ptr]; ..not as a clocked process. I'm not sure if this could be a problem.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The memory blocks in recent Altera FPGAs are synchronous only and don't support asynchronous access. When you do an asynchronous assignment, the synthesizer guesses which clock to use depending on how you synchronize the address and/or the data. In your case it may have selected the wrong clock.
To be sure that the synthesizer instantiates what you want, you should stick to the recommended HDL coding style in this document: http://www.altera.com/literature/hb/qts/qts_qii51007.pdf Have a look at the "Simple Dual-Port, Dual-Clock Synchronous RAM" example on pages 6-22 and 6-23.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Daixiwen,
Thanks a lot for your suggestions. Let me go through it in detail and try. -- Nishanth- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
How can I force the tool to infer these kind of rams using logic cells. Is there any directive which I can add in the RTL code? -- Nishanth- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
take a look at the ramstyle attribute:
http://quartushelp.altera.com/current/mergedprojects/hdl/vlog/vlog_file_dir_ram.htm- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks a lot for your replies. I feel this may solve the issue. -- Nishanth
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page