Hi Gabor,
I looked at the datasheets of:
- The Altera Cyclone IV series
((
https://www.altera.com/en_US/pdfs/literature/hb/cyclone-iv/cyiv-51003.pdf)
- The Xilinx 7 series
(
http://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf)
Now, technically, the CLaSH block RAM primitive is a:
- Dual port block RAM
- Operating in synchronous mode
The dual port means, that we have two address lines, which in our case
are a read address, and a write address. Synchronous mode means that
both the read and write address line are synchronised to the same clock.
Now, at the bottom of page 16 of the Cyclone IV memory block
documentation, in the section "Mixed-Port Read-During-Write Mode", which
is what we have, it says:
"This mode applies to a RAM in simple or true dual-port mode, which has
one port reading and the other port writing to the same address location
with the same clock. In this mode, you also have two output choices: Old
Data mode or Don't Care mode. In Old Data mode, a read-during-write
operation to different ports causes the RAM outputs to reflect the old
data at that address location. In Don't Care mode, the same operation
results in a “Don't Care” or unknown value on the RAM outputs"
As you can see, the "New Data" write mode is not an option in dual-port
operation for the Altera Cyclone IV. Now, moving to the latest Xilinx
7-series FPGAs, on page 18 and 19 of the memory recourses document, in
the section "Synchronous Clocking", it says:
"When one port performs a write operation, the write operation succeeds;
the other port can reliably read data from the same location if the
write port is in READ_FIRST mode. DATA_OUT on both ports then reflects
the previously stored data.
If the write port is in either WRITE_FIRST or in NO_CHANGE mode, then
the DATA_OUT on the read port would become invalid (unreliable). The
mode setting of the read-port does not affect this operation."
So, although WRITE_FIRST is an available option, the output in
synchronous dual-port mode on a conflicting read port would be
invalid/unreliable. So even though WRITE_FIRST is available, READ_FIRST
seems like the sensible choice.
So for both Xilinx and Altera devices, the "Old Data" or READ_FIRST mode
is the only available/sensible choice for our synchronous dual-port
blockRam primitive. We could add single-port blockRam primitives to
CLaSH, which has a single address line, and read and write enable
signals. For single-port block RAMs, "New Data" or WRITE_FIRST is
possible/sensible.
Please first consult your resident Xilinx FPGA expert first though.
Perhaps I'm misunderstanding the Xilinx documentation, and a reliable
WRITE_FIRST, dual port, synchronous Block RAM is possible on Xilinx
devices. In that case, I'm fine also with adding such a primitive.
However, I would like it to live in a new "CLaSH.Xilinx" module
hierarchy then.
Cheers,
Christiaan
On 12/20/2015 08:32 PM, Gabor Greif wrote:
>
> Altera seems to support new data mode at least since 2011
> (
https://www.altera.com/en_US/pdfs/literature/hb/cyclone-iv/cyiv-51003.pdf
> page 16).
>
> Xilinx al least since 2005
> (
http://www.xilinx.com/support/documentation/ip_documentation/sp_block_mem.pdf)
>
> Should I write an issue for this? (I can venture a try to implement it too).
>
> Cheers,
>
> Gabor
>
>
> Am Samstag, 19. Dezember 2015 11:44:23 UTC+1 schrieb Christiaan Baaij:
>
> Hi Gabor,
>
> It's very likely that Xilinx indeed natively support
> write-before-read, or, new-data-read. I think it's the same for Altera.
>
> However, when I implemented the blockRam primitive, I followed the
> Altera HDL coding guide, which recommends read-before-write
> (old-data-read).
>
> We can make new primitives, which implement write-before-read.
>
> -- Christiaan
>
> On 18 Dec 2015, at 10:51, Gabor Greif <
ggr...@gmail.com
>> <
https://github.com/ggreif/clash-ground/blob/f9bdfded1ae8ecf0a4962d444990842acbddc0c1/Histogram.hs>)
>>
>> When defining
>> > testInput' :: Signal (Unsigned 7)
>> > testInput' = stimuliGenerator $ 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> 0
>> :> 0 :> 0 :> 0 :> 0 :> 0 :> 0 :> Nil
>>
>> and sampling it like:
>>
>> *Main> L.drop 1 (sampleN 10 (topEntity testInput'))
>> [0,0,1,1,2,2,3,3,4]
>>
>> These repetitions must happen because the read and write addresses
>> coincide. But it surely looks like bug.
>> A xilinx blockRAM expert told me that a write and a read to the
>> same address is deterministically possible,
>> the write goes before the read and the read fetches what the write
>> has changed.
>>
>> Any hints?
>>
>> Thanks,
>>
>> Gabor
>>
>>
>>
>>
>> Am Samstag, 12. Dezember 2015 01:15:26 UTC+1 schrieb Gabor Greif:
>>
>> Thanks for the answers so far! I was also having a look at the
>> BlockRAM processor example and I believe I understand the
>> issues now.
>>
>> I have prepared a minimal example of a histogram, ready for
>> content/style review:
>>
https://github.com/ggreif/clash-ground/blob/master/Histogram.hs <
https://github.com/ggreif/clash-ground/blob/master/Histogram.hs>
>>
>> The obvious gotcha is that I do not (yet) handle the case of
>> equal read/write addresses, so the behavior is that of
>> read-after-write, and I miss counts.
>>
>> I'll try to fix that next.
>>
>> Cheers,
>>
>> Gabor
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "CLaSH - Hardware Description Language" group.
>> To unsubscribe from this group and stop receiving emails from it,
>> send an email to
clash-languag...@googlegroups.com <javascript:>.
>> <
https://groups.google.com/d/optout>.
>
> --
> You received this message because you are subscribed to the Google
> Groups "CLaSH - Hardware Description Language" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to
clash-languag...@googlegroups.com
> <mailto:
clash-languag...@googlegroups.com>.