Generate Statement Breaks UART RX VC
May 9, 2022 at 20:40 #1968
I have a DUT which takes in serial data, deframes it, and demux’s it out to a 21 peripheral UART’s for transmission.
I have written an OSVVM testbench for this, as an exercise in familiarizing myself with OSVVM, and I have ran into one issue. Everything else works amazingly.
In my test harness, instead of declaring 21 instances of a UART_RX VC to receive data from my DUT, I wrapped it up into a generate statement as follows.
UART_VC_gen : for i in 0 to 20 generate
UART_RXD : UartRx
DEFAULT_BAUD => UART_BAUD_PERIOD_115200
TransRec => Uart_rec(i),
SerialDataIn => serial_data_tx(i)
end generate UART_VC_gen;
I used array types of the appropriate records and serial data lines.
Everything worked well until I implemented scoreboarding to check my data, at which point it became apparent that the individual UARTs were somehow getting mixed up data. I verified that the UART serial data coming out of the DUT was correct, and so I concluded that the issue was with the VC.
My first step in debugging this issue was to unroll the generate statement and declare each VC individually, still using the record array, just indexing manually. lo and behold, this fixed the issue. The only difference that I can see is that the scoreboard_report.yml indicates that I now have 21 receive FIFO’s as well as 21 Scoreboards, whereas before I only had 1 receive FIFO and 21 Scoreboards.
This explains how the UART’s were getting access to each others data in the VC, and leads me to believe that somehow I am not generating the correct number of FIFO’s with my generate statement. As I mentioned, the issue is now fixed, but I would like to know if this is just a bug, or a misuse of OSVVM on my part. I much prefer the concise generate statement to individual VC declarations.
I apologize for the long winded question, but if you have any thoughts on this, I’d love to hear them.
MichaelMay 9, 2022 at 22:26 #1969
Thanks for the long winded question – it gives me the information I need.
It looks like the instance name is the same for all instances of the UART.
As a result statement that constructs the ReceiveFifo is connecting them all
together. Currently this:
ReceiveFifo <= NewID("ReceiveFifo", ID, ReportMode => DISABLED) ;
It is just an OSVVM oversight and easy to fix. Changing it to the following and your generate loop should be ok.
ReceiveFifo <= NewID("ReceiveFifo", ID, ReportMode => DISABLED, Search => PRIVATE) ;
If the VC really do have the instance label, then they will also have the same AlertLogID.
In the AXI VC, there is a generic that allows this to be set and the string value of the
generate index can be appended to the name. I should have an official fix shortly.
I will need to simulate it first before I am able to push it though.
JimMay 9, 2022 at 22:31 #1970
Thanks for the quick response Jim! I will try to get it working on my end in the meantime, just for the sake of getting deeper into the weeds with OSVVM.
I am simulating with Aldec Riviera Pro v.2019.10
MichaelMay 9, 2022 at 23:02 #1971
I went ahead and changed the code and it fixed the issue. Thank you!
One more quick question, my DUT also does the reverse… takes data from 21 UARTs and mux’s it all to one serial output. So while I haven’t gotten around to it yet, the next part of my test bench is going to have 21 UART_TX VC’s in it.
Would I be correct in assuming that I would run into a similar issue with a UART_TX generate statement, and if so, would the same code change fix it? I know you’re going to push out a fix here shortly, I was just curious.
MichaelMay 10, 2022 at 04:46 #1972
Unfortunately this impacts all OSVVM VC. So the same change is needed for the UartTx.
Are you using sources from OSVVM.org or GitHub? I have updated the GitHub dev branch. I will update the main branch tomorrow. If you are using sources from OSVVM.org, I will update them too, otherwise, they will be updated when 2022.05 is released.
With the addition of the MODEL_ID_NAME, the recommended practice will be:
UART_VC_gen : for i in 0 to 20 generate UART_RXD : UartRx generic map ( MODEL_ID_NAME => "UartRx_" & to_string(i), DEFAULT_BAUD => UART_BAUD_PERIOD_115200 ) port map ( TransRec => Uart_rec(i), SerialDataIn => serial_data_tx(i) ); end generate UART_VC_gen;
I did not actually test the above code, but I did test similar code that is in OsvvmLibraries/AXI4/Axi4/testbench_MultipleMemory/TbAxi4_MultipleMemory_Generate.vhd
Again this test case is on the dev branch of the Axi4 libraries.
JimMay 10, 2022 at 16:35 #1973
I have pushed the updated code to the main branch now.May 16, 2022 at 18:25 #1975
Thanks for all the support Jim!
- You must be logged in to reply to this topic.