Skip to content

Conversation

@gaborszita
Copy link
Contributor

Classes MemBlock and _MemIndexed are now fully covered by tests, except one exception that I don't think can happen (see #460)

@codecov
Copy link

codecov bot commented Jan 11, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.9%. Comparing base (5077c24) to head (43453ef).
Report is 9 commits behind head on development.

Additional details and impacted files
@@              Coverage Diff              @@
##           development    #461     +/-   ##
=============================================
+ Coverage         91.7%   91.9%   +0.3%     
=============================================
  Files               24      24             
  Lines             6403    6413     +10     
=============================================
+ Hits              5866    5888     +22     
+ Misses             537     525     -12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@fdxmw fdxmw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for improving these tests! I have some minor comments


def test_negative_bitwidth(self):
with self.assertRaises(pyrtl.PyrtlError):
pyrtl.MemBlock(-1, 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines like these are a little easier to read with keyword arguments (pyrtl.MemBlock(bitwidth=-1, addrwidth=1)) as the reader may not remember whether bitwidth or addrwidth comes first.

If you agree and want to change this, please change it consistently throughout this commit

with self.assertRaises(pyrtl.PyrtlError):
mem_out <<= mem[mem_in]

def test_memblock_write_data_larger_than_memory_bidwidth(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: bidwidth :)


def test_memindex_bitwidth_more_than_addrwidth(self):
mem = pyrtl.MemBlock(1, 1)
mem_in = pyrtl.Input(2, 'mem_in')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name mem_in is confusing in this commit as it's sometimes the address, and sometimes the data to write. Seems clearer to always call the address mem_addr?

with self.assertRaises(pyrtl.PyrtlError):
pyrtl.MemBlock(1, -1)

def test_memindex_bitwidth_more_than_addrwidth(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call this greater_than instead of more_than ?

Regardless, the word choice here should be consistent with the next test (more vs larger)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the name to test_memindex_bitwidth_greater_than_addrwidth, but I left test_memblock_write_data_larger_than_memory_bitwidth as it is because I think when we talk about numbers it is better to say greater and less and when we talk about data it is better to say larger and smaller. But I can change it if you disagree.

for i in range(8):
mem_out_array[i] <<= mem[mem_in][i]
mem_value_map = {mem: {0: 7, 1: 5}}
sim_trace = pyrtl.SimulationTrace()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a SimulationTrace shouldn't be needed here since Simulation should create a SimulationTrace for you if none is provided (happens again in the next two tests)

mem_value_map = {mem: {0: 7, 1: 5}}
sim_trace = pyrtl.SimulationTrace()
sim = pyrtl.Simulation(tracer=sim_trace, memory_value_map=mem_value_map)
for i in range(len(mem_value_map[mem])):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem like we gain much by testing both addresses? Consider just checking the first address as loops like these make it harder to debug the test. When a test failure occurs, we won't know the values of i or j

sim.step({mem_in: i})
binary = bin(mem_value_map[mem][i])[2:].zfill(8)
for j in range(8):
self.assertEqual(sim.inspect(mem_out_array[j]), int(binary[7 - j]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, it's a little better to reassemble the inspected binary value, and then do one big assertEqual, rather than doing one assertEqual for each bit in the loop. With one big assertEqual, the test failure error message will be better, since we can more easily see which bits are wrong. With the single-bit assertEqual, the error message will just tell us that 0 is not equal to 1 or vice versa.

You can reassemble the inspected values with something like:

>>> def reassemble_bits(bits: list[int]):
...     value = 0
...     for bit in bits:
...         value = (value << 1) | bit
...     return value
>>> reassemble_bits([0, 0])
0
>>> reassemble_bits([0, 1])
1
>>> reassemble_bits([1, 0])
2
>>> reassemble_bits([1, 1])
3

If you want to keep things the way they are, consider moving this logic to check if the Nth bit is set to a helper function, as it's a bit complicated and it's repeated in the next two tests.

Also you can check this a little more easily with bitmasks and bitwise AND, something like

>>> def check_nth_bit(value: int, n: int):
...     return bool(value & (1 << n))
>>> for n in range(8):
...     print(n, check_nth_bit(27, n))
...
0 True
1 True
2 False
3 True
4 True
5 False
6 False
7 False

@gaborszita gaborszita requested a review from fdxmw January 17, 2025 23:15
@fdxmw fdxmw merged commit 5b282f3 into UCSBarchlab:development Jan 18, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants