<pepijndevos>
Would love to chat with someone familiar with memory interference how to map HDL to memrd and memwr and mem and rtlil::Memory stuff
<whitequark>
sure
<whitequark>
i implemented that in nmigen
<pepijndevos>
yay
<pepijndevos>
so I'm looking at GHDL and how to map that to yosys constructs
<whitequark>
re shift/shiftx: i believe that's the same as shr, except it maps to the verilog indexed part-select construct
<whitequark>
i'm not sure if yosys ever emits shift (as opposed to shiftx)
<pepijndevos>
So if I make an 1024 array of 8 bit elements, it gets synthesized into a 8191 lenght flat vector
<pepijndevos>
then there is a memidx primitive that seems to translate and index to the flattened array
<whitequark>
hmm
<whitequark>
that seems troublesome
<pepijndevos>
and there is a dyn_extract and dyn_insert that is basically a non-constant array lookup
<pepijndevos>
So in yosys, is memory of a specified dimension?
<whitequark>
yep
<pepijndevos>
Hrm... I can maybe discuss with Tristan to delete the whole flattening and memidx step
<pepijndevos>
But okay, so either I need to "unflatten" that or skip that step in GHDL
<pepijndevos>
So say I have just an array of std_logic_vector, how would I map that to yosys memory things?
<whitequark>
let's see
attie has joined #yosys
<whitequark>
pepijndevos: right, so, you could map either to $mem cells, or $memrd/$memwr/$meminit
<whitequark>
do you know which one is closer to your existing IR in that case?
<whitequark>
i.e. how does GHDL represent ports?
<pepijndevos>
As far as I understand, currently there is no "port" per se, but a dyn_extract and dyn_insert primitive that are basically arra[idx] and array[idx]=val
<whitequark>
ok
<whitequark>
those map directly to $memrd and $memwr
<whitequark>
basically you assign some index to each distinct `array` and use it as \MEMID parameter
<pepijndevos>
So do you need to convert arrays to RTLIL::Memory instances?
<whitequark>
nope
<whitequark>
i mean, you could
<whitequark>
soryr
<whitequark>
*sorry, you do
<whitequark>
I misremembered how this works
<whitequark>
each memory is converted to RTLIL::Memory, and then $memrd/$memwr ports are associated to it by name (via \MEMID)
<whitequark>
the geometry of the memory is duplicated, for RTLIL::Memory and then in each port
<pepijndevos>
Hm okay
<pepijndevos>
(I have NO idea what would map to meminit in VHDL)
<whitequark>
how do you initialize memories in VHDL?
<pepijndevos>
I googled it and I'm still not sure... you pretty much don't??? Or in some vendor specific way or something that only works in simulation.
<whitequark>
huh
<ZirconiumX>
That's odd.
<pepijndevos>
Like... there isn't anything like readmemb() either
<pepijndevos>
so people just reset arrays in reset and do manual file IO bs
<ZirconiumX>
And I almost had respect for VHDL :P
<whitequark>
reset arrays in reset?
<pepijndevos>
Yea, like you reset other values... if reset memory = initial value, doesn't map to bram in any useful way...
<ZirconiumX>
So it gets initialised by logic?
<ZirconiumX>
That's, uh, not great.
Xiretza has joined #yosys
<whitequark>
I'm thinking it is mostly ASIC-geared then
<ZirconiumX>
I mean, it was originally written for ASICs, but I would have thought they'd expand it to handle this
<daveshah>
It definitely supports initialised registers
<daveshah>
With a := value after the signal declaration
umarcor has joined #yosys
<daveshah>
I'm pretty sure this works for initialised BRAM too
<umarcor>
@pepijndevos, I think the reason to use IO for simulation is that the same functions can be used to read different data files, instead of copying large sets of raw values in the codebase. however, I've seen packages used to define constants (memory initialization values) only.
attie has quit [Read error: Connection reset by peer]
<umarcor>
regarding initialization of BRAMs (as opposed to arrays of registers), I think that it is vendor-specific. IIRC, Xilinx (ISE or Vivado) will populate the BRAM with the values you define either as @daveshah commented, or with the reset values of the process from where the BRAM is inferred. I don't know which one is picked when both exist.
<umarcor>
when the BRAM is defined as an IP-core in Vivado, a bin or hex file can be provided.
<umarcor>
last, cli tools exist to overwritten the initialization values of BRAMs in bitstreams. these are provided in the SDK, since they are meant for software developers that don't have access to the sources of the hardware design. I'm afraid that none of this is open source.
<whitequark>
icestorm has such an open source tool
<whitequark>
called "icebram"
<umarcor>
exactly
dys has joined #yosys
<umarcor>
but it targets lattice device only, for now, isn't it?
<whitequark>
icestorm targets ice40 specifically
<umarcor>
is the reverse engineering effort around xilinx's 7 series mature enough to adapt it?
<mwk>
hmm
<mwk>
how does icebram know which blockram to target?
<whitequark>
i know very little about xilinx, but i thought the BRAM frames were among the easiest to work with
<whitequark>
mwk: you fill it with a pattern first
<mwk>
ew
<whitequark>
you have to do it because the geometry may change quite a bit
<whitequark>
e.g. yosys can change aspect ratio and duplicate BRAMs
<mwk>
because of address lines being swizzled?
<mwk>
hmm
<whitequark>
and that too
<mwk>
tbh that sounds like something we should invent a metadata format for
<whitequark>
possibly, but i think the approach of filling it with a pattern works fine
<mwk>
feels hacky
<whitequark>
as long as you always have an unique mapping, is it?
<mwk>
unique mapping?
<mwk>
you just said that brams can get duplicated
<whitequark>
i mean, as long as the pattern is sufficiently random that you don't get collisions
* mwk
was considering something some time ago
<mwk>
a "relocation" mechanism
<mwk>
mark a BRAM / LUT / generic attribute as "to be resolved later" somehow in .v
<mwk>
let it pass through synth + pnr unchanged
<mwk>
and have it resolved at bitstream creation point
<whitequark>
vivado has almost this, no?
<whitequark>
where you can manipulate post-synthesis netlist
<mwk>
sort of, yes
<whitequark>
give your BRAM or LUT an attribute and grab it with tcl
<mwk>
hmm
<mwk>
right, that would work
<mwk>
anyhow, the "relocation" approach would work for things smaller than whole blockrams, ideally
<mwk>
like single LUTs
<mwk>
or, the case I was thinking of, PLL parameters
<whitequark>
yes, sb used it for PLL parameters
<mwk>
so you can tune your PLL without re-pnring and changing timing in the process
<whitequark>
when the bitstream would build for hours
<mwk>
sb?
<whitequark>
sebastien from m-labs
<mwk>
oh
<pepijndevos>
whitequark, talking to Tristan now, and the worry is that some uses of 2D array don't map to memories, and Yosys doesn't do 2D arrays apparently. So the only general approach seems to flatten everything and then have a whole pass to extract and unflatten memories -.-
<whitequark>
personally, i think that the propensity of HDL toolchains to leave the most important properties of your design (like whether something gets mapped to BRAM) to "inference" is one of the absolute worst things about them
<whitequark>
but people seem to like that approach anyway, so i guess go for it
<pepijndevos>
Yea, so from what I gather in Verilog `reg [20] foo [8]` indicates an array of 20 elements of 8 bits, but VHDL doesn't really have a distinction like that. You just make arrays or arrays of arrays of arrays of bits
<mwk>
pepijndevos: 8 elements of 20 bits, and you write it as reg[19:0] foo [0:7]
<mwk>
and in systemverilog IIRC you can do reg[19:0] foo [0:7][0:9]
<mwk>
and as for xilinx and memory frames, uh
<mwk>
suppose you want to make a xilinxbram tool
<pepijndevos>
So how does yosys decide what to do with a reg [x:y] foo [a:b]? Does that always become a memory, or can you do non-memory things to it that cause it to just become logic?
<mwk>
first, you get to parse and re-emit the bitstream
<mwk>
which requires full geometry information about the chip already
<mwk>
second, you need a map of the bits in a blockram tile and information about the particular arrangement
<emily>
I think mwk might be a little familiar with Xilinx reverse-engineering efforts...
<whitequark>
lol
<mwk>
which depend on many things
<mwk>
mostly 18k vs 36k size and TDP vs SDP
<mwk>
I've looked at the blockram bits geometry, and... I suppose there is some logic to it, but it mostly looks like a big mess
<mwk>
anyhow, such a tool can definitely be done
<mwk>
atm I think I have enough data to do that for everything from xc2v up to xc7
<Xiretza>
emily: hah, woops. I don't really follow the developments very closely and didn't associate the name :)
<mwk>
but that's quite a bit of effort, and given that both ISE and Vivado already include such a tool, I don't see it as high-priority
emeb has joined #yosys
craigo has joined #yosys
gkh has joined #yosys
citypw has quit [Ping timeout: 252 seconds]
Jybz has quit [Ping timeout: 276 seconds]
Jybz has joined #yosys
<mwk>
that may be a stupid question, but... what does "coarse-grain synthesis" refer to in yosys? (looking at splice and connwrappers command help)
<whitequark>
mwk: synthesis to multibit cells
<whitequark>
like there's $and which has n-bit inputs and outputs
<whitequark>
and $_AND_ which has strictly 1-bit
<mwk>
oh, just that
<mwk>
still don't understand what these two commands are useful for, though...
<mwk>
they don't seem to be called in the course of normal synthesis
<mwk>
"This command adds $slice and $concat cells to the design to make the splicing of multi-bit signals explicit. This for example is useful for coarse grain synthesis, where dedicated hardware is needed to splice signals."
<mwk>
ok, I definitely don't understand what dedicated hardware that would be
<daveshah>
Coarse grain reconfigurable arrays
<daveshah>
Which I guess might be based on buses internally and therefore have special resources for manipulating those buses
<whitequark>
huh, never heard of those. any links?
<emily>
I think it was meant as a hypothetical?
<emily>
apparently not
<daveshah>
I don't think there are any you can buy
<daveshah>
Lots of papers
<mwk>
some crazy research thing?
<mwk>
ah, figures
<daveshah>
I think some modern apps processors have structures a bit like them for image sensor pipelines etc
<daveshah>
But good luck finding any docs or info for them