UCSBarchlab / PyRTL

A collection of classes providing simple hardware specification, simulation, tracing, and testing suitable for teaching and research. Simplicity, usability, clarity, and extensibility are the overarching goals, rather than performance or optimization.
http://ucsbarchlab.github.io/PyRTL
BSD 3-Clause "New" or "Revised" License
253 stars 76 forks source link

ROM not working as expected (16 bit address & 16 bit data) #423

Closed kfeiste closed 2 years ago

kfeiste commented 2 years ago

The ROM isn't working as I expect. The first data value comes out correctly, but then it's garbage until the data values that can be represented in less than 8 bits. The rom_data_func is printing the values I expect, but they don't propagate through to the output.

import pyrtl
from pyrtl import  *

########################################################################
########################################################################
rom_dict = {
    0 : 1000 ,
    1 : 2000 ,
    2 : 3000 ,
    3 : 4000 ,
    4 : 5000 ,
    5 : 6000 ,
    6 : 7000 ,
    7 : 8000 ,
 1000 : 1010 ,
 1001 : 2020 ,
 1002 : 3030 ,
 1003 : 4040 ,
 1004 : 5050 ,
 1005 : 6060 ,
 1006 : 7070 ,
 1007 : 8080 ,
}

########################################################################
########################################################################
def rom_data_func(address):
   if address in rom_dict:
       data = rom_dict[address]
   else:
       data = address
   print("*",address,data)
   return data

rom1 = RomBlock(bitwidth=16, addrwidth=16, romdata=rom_data_func, max_read_ports=1)

rom1_addr = Input(16, "addr")
rom1_out  = Output(16, "data")

rom1_data = rom1[rom1_addr]
rom1_out  <<= rom1_data

########################################################################
########################################################################
print()
print("---------roms----------")
print(pyrtl.working_block())
simvals = {
    'addr': list(range(0,20)) + list(range(1000,1020)) + list(range(12000,12020))
}
print(simvals['addr'])

sim_trace = pyrtl.SimulationTrace()
sim = pyrtl.Simulation(tracer=sim_trace)
sim.step_multiple(simvals)
sim_trace.render_trace()
---------roms----------
tmp1/16W <-- m --  tmp0[addr/16I](memid=0)
data/16O <-- w -- tmp1/16W 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 12000, 12001, 12002, 12003, 12004, 12005, 12006, 12007, 12008, 12009, 12010, 12011, 12012, 12013, 12014, 12015, 12016, 12017, 12018, 12019]
* 0 1000
* 1 2000
* 2 3000
* 3 4000
* 4 5000
* 5 6000
* 6 7000
* 7 8000
* 8 8
* 9 9
* 10 10
* 11 11
* 12 12
* 13 13
* 14 14
* 15 15
* 16 16
* 17 17
* 18 18
* 19 19
* 1000 1010
* 1001 2020
* 1002 3030
* 1003 4040
* 1004 5050
* 1005 6060
* 1006 7070
* 1007 8080
* 1008 1008
* 1009 1009
* 1010 1010
* 1011 1011
* 1012 1012
* 1013 1013
* 1014 1014
* 1015 1015
* 1016 1016
* 1017 1017
* 1018 1018
* 1019 1019
* 12000 12000
* 12001 12001
* 12002 12002
* 12003 12003
* 12004 12004
* 12005 12005
* 12006 12006
* 12007 12007
* 12008 12008
* 12009 12009
* 12010 12010
* 12011 12011
* 12012 12012
* 12013 12013
* 12014 12014
* 12015 12015
* 12016 12016
* 12017 12017
* 12018 12018
* 12019 12019
     ▏0                        ▏5                        ▏10                       ▏15                       ▏20                       ▏25                       ▏30                       ▏35                       ▏40                       ▏45                       ▏50                       ▏55                      

addr 0x0  ╳0x1 ╳0x2 ╳0x3 ╳0x4  ╳0x5 ╳0x6 ╳0x7 ╳0x8 ╳0x9  ╳0xa ╳0xb ╳0xc ╳0xd ╳0xe  ╳0xf ╳0x10╳0x11╳0x12╳0x13 ╳0x3e╳0x3e╳0x3e╳0x3e╳0x3e ╳0x3e╳0x3e╳0x3e╳0x3f╳0x3f ╳0x3f╳0x3f╳0x3f╳0x3f╳0x3f ╳0x3f╳0x3f╳0x3f╳0x3f╳0x3f ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e

data 0x3e8╳0x7d╳0xbb╳0xfa╳0x13 ╳0x17╳0x1b╳0x1f╳0x8 ╳0x9  ╳0xa ╳0xb ╳0xc ╳0xd ╳0xe  ╳0xf ╳0x10╳0x11╳0x12╳0x13 ╳0x3f╳0x7e╳0xbd╳0xfc╳0x13 ╳0x17╳0x1b╳0x1f╳0x3f╳0x3f ╳0x3f╳0x3f╳0x3f╳0x3f╳0x3f ╳0x3f╳0x3f╳0x3f╳0x3f╳0x3f ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e ╳0x2e╳0x2e╳0x2e╳0x2e╳0x2e
fdxmw commented 2 years ago

This looks like a rendering bug in render_trace(), it doesn't seem to be reserving the correct number of characters to print the data. Until the bug is fixed, I believe you can work around it for now by overriding symbol_len, like this:

sim_trace.render_trace(symbol_len=8)

With that change to your code, I get this output, which appears to be correct:

addr 0x0     ╳0x1    ╳0x2    ╳0x3    ╳0x4     ╳0x5    ╳0x6    ╳0x7    ╳0x8    ╳0x9     ╳0xa    ╳0xb    ╳0xc    ╳0xd    ╳0xe     ╳0xf    ╳0x10   ╳0x11   ╳0x12   ╳0x13    ╳0x3e8  ╳0x3e9  ╳0x3ea  ╳0x3eb  ╳0x3ec   ╳0x3ed  ╳0x3ee  ╳0x3ef  ╳0x3f0  ╳0x3f1   ╳0x3f2  ╳0x3f3  ╳0x3f4  ╳0x3f5  ╳0x3f6   ╳0x3f7  ╳0x3f8  ╳0x3f9  ╳0x3fa  ╳0x3fb   ╳0x2ee0 ╳0x2ee1 ╳0x2ee2 ╳0x2ee3 ╳0x2ee4  ╳0x2ee5 ╳0x2ee6 ╳0x2ee7 ╳0x2ee8 ╳0x2ee9  ╳0x2eea ╳0x2eeb ╳0x2eec ╳0x2eed ╳0x2eee  ╳0x2eef ╳0x2ef0 ╳0x2ef1 ╳0x2ef2 ╳
0x2ef3

data 0x3e8   ╳0x7d0  ╳0xbb8  ╳0xfa0  ╳0x1388  ╳0x1770 ╳0x1b58 ╳0x1f40 ╳0x8    ╳0x9     ╳0xa    ╳0xb    ╳0xc    ╳0xd    ╳0xe     ╳0xf    ╳0x10   ╳0x11   ╳0x12   ╳0x13    ╳0x3f2  ╳0x7e4  ╳0xbd6  ╳0xfc8  ╳0x13ba  ╳0x17ac ╳0x1b9e ╳0x1f90 ╳0x3f0  ╳0x3f1   ╳0x3f2  ╳0x3f3  ╳0x3f4  ╳0x3f5  ╳0x3f6   ╳0x3f7  ╳0x3f8  ╳0x3f9  ╳0x3fa  ╳0x3fb   ╳0x2ee0 ╳0x2ee1 ╳0x2ee2 ╳0x2ee3 ╳0x2ee4  ╳0x2ee5 ╳0x2ee6 ╳0x2ee7 ╳0x2ee8 ╳0x2ee9  ╳0x2eea ╳0x2eeb ╳0x2eec ╳0x2eed ╳0x2eee  ╳0x2eef ╳0x2ef0 ╳0x2ef1 ╳0x2ef2 ╳
0x2ef3