From ac1707d7d47bad078cad3fbec3343158a455c6b4 Mon Sep 17 00:00:00 2001 From: Gabor Szita Date: Fri, 10 Jan 2025 17:37:54 -0800 Subject: [PATCH 1/4] Add more tests for MemBlock and _MemIndexed --- tests/test_memblock.py | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/tests/test_memblock.py b/tests/test_memblock.py index 351804af..33d5f9ab 100644 --- a/tests/test_memblock.py +++ b/tests/test_memblock.py @@ -101,6 +101,44 @@ def test_memblock_added_default_named(self): mem = pyrtl.MemBlock(32, 8) self.assertIs(pyrtl.working_block().get_memblock_by_name(mem.name), mem) +class RTLMemBlockErrorTests(unittest.TestCase): + def setUp(self): + pyrtl.reset_working_block() + + def test_negative_bitwidth(self): + with self.assertRaises(pyrtl.PyrtlError): + pyrtl.MemBlock(-1, 1) + + def test_negative_addrwidth(self): + with self.assertRaises(pyrtl.PyrtlError): + pyrtl.MemBlock(1, -1) + + def test_memindex_bitwidth_more_than_addrwidth(self): + mem = pyrtl.MemBlock(1, 1) + mem_in = pyrtl.Input(2, 'mem_in') + mem_out = pyrtl.Output(1, 'mem_out') + with self.assertRaises(pyrtl.PyrtlError): + mem_out <<= mem[mem_in] + + def test_memblock_write_data_larger_than_memory_bidwidth(self): + mem = pyrtl.MemBlock(1, 1) + mem_addr = pyrtl.Input(1, 'mem_addr') + mem_in = pyrtl.Input(2, 'mem_in') + with self.assertRaises(pyrtl.PyrtlError): + mem[mem_addr] <<= mem_in + + def test_memblock_enable_signal_not_1_bit(self): + mem = pyrtl.MemBlock(1, 1) + mem_addr = pyrtl.Input(1, 'mem_addr') + mem_in = pyrtl.Input(1, 'mem_in') + with self.assertRaises(pyrtl.PyrtlError): + mem[mem_addr] <<= pyrtl.MemBlock.EnabledWrite(mem_in, enable=pyrtl.Input(2)) + + def test_read_ports_exception(self): + mem = pyrtl.MemBlock(1, 1) + with self.assertRaises(pyrtl.PyrtlError): + mem.read_ports() + class MemIndexedTests(unittest.TestCase): def setUp(self): @@ -229,6 +267,53 @@ def test_write_memindexed_ior(self): self.assertEqual(self.mem1.num_read_ports, 1) self.assertEqual(self.mem2.num_write_ports, 1) + def test_memindexed_len(self): + self.mem = pyrtl.MemBlock(8, 1) + self.assertEqual(len(self.mem[0]), 8) + self.mem_2= pyrtl.MemBlock(16, 1) + self.assertEqual(len(self.mem_2[0]), 16) + + def test_memindexed_getitem(self): + mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1, max_read_ports=None) + mem_in = pyrtl.Input(1, 'mem_in') + mem_out_array = [pyrtl.Output(8, 'mem_out_' + str(i)) for i in range(8)] + 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() + sim = pyrtl.Simulation(tracer=sim_trace, memory_value_map=mem_value_map) + for i in range(len(mem_value_map[mem])): + 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])) + + def test_memindexed_sign_extended(self): + mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) + mem_in = pyrtl.Input(1, 'mem_in') + mem_out = pyrtl.Output(16, 'mem_out') + mem_out <<= mem[mem_in].sign_extended(16) + mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} + mem_value_map_sign_extended = [0b0000000000101101, 0b1111111110011011]; + 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])): + sim.step({mem_in: i}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_sign_extended[i]) + + def test_memindexed_zero_extended(self): + mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) + mem_in = pyrtl.Input(1, 'mem_in') + mem_out = pyrtl.Output(16, 'mem_out') + mem_out <<= mem[mem_in].zero_extended(16) + mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} + mem_value_map_zero_extended = [0b0000000000101101, 0b0000000010011011]; + 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])): + sim.step({mem_in: i}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_zero_extended[i]) + class RTLRomBlockWiring(unittest.TestCase): data = list(range(2**5)) From d0c12b6200f3b188a90b12e033500e78627ea9dc Mon Sep 17 00:00:00 2001 From: Gabor Szita Date: Fri, 10 Jan 2025 17:47:14 -0800 Subject: [PATCH 2/4] fix pycodestyle errors --- tests/test_memblock.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/test_memblock.py b/tests/test_memblock.py index 33d5f9ab..db5f4261 100644 --- a/tests/test_memblock.py +++ b/tests/test_memblock.py @@ -101,6 +101,7 @@ def test_memblock_added_default_named(self): mem = pyrtl.MemBlock(32, 8) self.assertIs(pyrtl.working_block().get_memblock_by_name(mem.name), mem) + class RTLMemBlockErrorTests(unittest.TestCase): def setUp(self): pyrtl.reset_working_block() @@ -112,7 +113,7 @@ def test_negative_bitwidth(self): def test_negative_addrwidth(self): with self.assertRaises(pyrtl.PyrtlError): pyrtl.MemBlock(1, -1) - + def test_memindex_bitwidth_more_than_addrwidth(self): mem = pyrtl.MemBlock(1, 1) mem_in = pyrtl.Input(2, 'mem_in') @@ -270,9 +271,9 @@ def test_write_memindexed_ior(self): def test_memindexed_len(self): self.mem = pyrtl.MemBlock(8, 1) self.assertEqual(len(self.mem[0]), 8) - self.mem_2= pyrtl.MemBlock(16, 1) + self.mem_2 = pyrtl.MemBlock(16, 1) self.assertEqual(len(self.mem_2[0]), 16) - + def test_memindexed_getitem(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1, max_read_ports=None) mem_in = pyrtl.Input(1, 'mem_in') @@ -286,7 +287,7 @@ def test_memindexed_getitem(self): 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])) + self.assertEqual(sim.inspect(mem_out_array[j]), int(binary[7 - j])) def test_memindexed_sign_extended(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) @@ -294,20 +295,20 @@ def test_memindexed_sign_extended(self): mem_out = pyrtl.Output(16, 'mem_out') mem_out <<= mem[mem_in].sign_extended(16) mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} - mem_value_map_sign_extended = [0b0000000000101101, 0b1111111110011011]; + mem_value_map_sign_extended = [0b0000000000101101, 0b1111111110011011] 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])): sim.step({mem_in: i}) self.assertEqual(sim.inspect(mem_out), mem_value_map_sign_extended[i]) - + def test_memindexed_zero_extended(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) mem_in = pyrtl.Input(1, 'mem_in') mem_out = pyrtl.Output(16, 'mem_out') mem_out <<= mem[mem_in].zero_extended(16) mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} - mem_value_map_zero_extended = [0b0000000000101101, 0b0000000010011011]; + mem_value_map_zero_extended = [0b0000000000101101, 0b0000000010011011] 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])): From 85db0f6612c187b3e4b89a5a3ac857e588a491c7 Mon Sep 17 00:00:00 2001 From: Gabor Szita Date: Fri, 17 Jan 2025 15:03:49 -0800 Subject: [PATCH 3/4] Address feedback --- tests/test_memblock.py | 74 ++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/tests/test_memblock.py b/tests/test_memblock.py index db5f4261..e629da2d 100644 --- a/tests/test_memblock.py +++ b/tests/test_memblock.py @@ -108,35 +108,35 @@ def setUp(self): def test_negative_bitwidth(self): with self.assertRaises(pyrtl.PyrtlError): - pyrtl.MemBlock(-1, 1) + pyrtl.MemBlock(bitwidth=-1, addrwidth=1) def test_negative_addrwidth(self): with self.assertRaises(pyrtl.PyrtlError): - pyrtl.MemBlock(1, -1) + pyrtl.MemBlock(bitwidth=1, addrwidth=-1) - def test_memindex_bitwidth_more_than_addrwidth(self): - mem = pyrtl.MemBlock(1, 1) - mem_in = pyrtl.Input(2, 'mem_in') + def test_memindex_bitwidth_greater_than_addrwidth(self): + mem = pyrtl.MemBlock(bitwidth=1, addrwidth=1) + mem_addr = pyrtl.Input(2, 'mem_addr') mem_out = pyrtl.Output(1, 'mem_out') with self.assertRaises(pyrtl.PyrtlError): - mem_out <<= mem[mem_in] + mem_out <<= mem[mem_addr] - def test_memblock_write_data_larger_than_memory_bidwidth(self): - mem = pyrtl.MemBlock(1, 1) + def test_memblock_write_data_larger_than_memory_bitwidth(self): + mem = pyrtl.MemBlock(bitwidth=1, addrwidth=1) mem_addr = pyrtl.Input(1, 'mem_addr') mem_in = pyrtl.Input(2, 'mem_in') with self.assertRaises(pyrtl.PyrtlError): mem[mem_addr] <<= mem_in def test_memblock_enable_signal_not_1_bit(self): - mem = pyrtl.MemBlock(1, 1) + mem = pyrtl.MemBlock(bitwidth=1, addrwidth=1) mem_addr = pyrtl.Input(1, 'mem_addr') mem_in = pyrtl.Input(1, 'mem_in') with self.assertRaises(pyrtl.PyrtlError): mem[mem_addr] <<= pyrtl.MemBlock.EnabledWrite(mem_in, enable=pyrtl.Input(2)) def test_read_ports_exception(self): - mem = pyrtl.MemBlock(1, 1) + mem = pyrtl.MemBlock(bitwidth=1, addrwidth=1) with self.assertRaises(pyrtl.PyrtlError): mem.read_ports() @@ -269,51 +269,55 @@ def test_write_memindexed_ior(self): self.assertEqual(self.mem2.num_write_ports, 1) def test_memindexed_len(self): - self.mem = pyrtl.MemBlock(8, 1) + self.mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) self.assertEqual(len(self.mem[0]), 8) - self.mem_2 = pyrtl.MemBlock(16, 1) + self.mem_2 = pyrtl.MemBlock(bitwidth=16, addrwidth=1) self.assertEqual(len(self.mem_2[0]), 16) + def reassemble_bits(bits: list[int]): + value = 0 + for bit in bits: + value = (value << 1) | bit + return value + def test_memindexed_getitem(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1, max_read_ports=None) - mem_in = pyrtl.Input(1, 'mem_in') + mem_addr = pyrtl.Input(1, 'mem_addr') mem_out_array = [pyrtl.Output(8, 'mem_out_' + str(i)) for i in range(8)] for i in range(8): - mem_out_array[i] <<= mem[mem_in][i] + mem_out_array[i] <<= mem[mem_addr][i] 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])): - 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])) + sim = pyrtl.Simulation(memory_value_map=mem_value_map) + sim.step({mem_addr: 0}) + binary = bin(mem_value_map[mem][0])[2:].zfill(8) + self.assertEqual([sim.inspect(mem_out_array[j]) for j in range(8)], + [int(binary[7 - j]) for j in range(8)]) def test_memindexed_sign_extended(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) - mem_in = pyrtl.Input(1, 'mem_in') + mem_addr = pyrtl.Input(1, 'mem_addr') mem_out = pyrtl.Output(16, 'mem_out') - mem_out <<= mem[mem_in].sign_extended(16) + mem_out <<= mem[mem_addr].sign_extended(16) mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} mem_value_map_sign_extended = [0b0000000000101101, 0b1111111110011011] - 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])): - sim.step({mem_in: i}) - self.assertEqual(sim.inspect(mem_out), mem_value_map_sign_extended[i]) + sim = pyrtl.Simulation(memory_value_map=mem_value_map) + sim.step({mem_addr: 0}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_sign_extended[0]) + sim.step({mem_addr: 1}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_sign_extended[1]) def test_memindexed_zero_extended(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1) - mem_in = pyrtl.Input(1, 'mem_in') + mem_addr = pyrtl.Input(1, 'mem_addr') mem_out = pyrtl.Output(16, 'mem_out') - mem_out <<= mem[mem_in].zero_extended(16) + mem_out <<= mem[mem_addr].zero_extended(16) mem_value_map = {mem: {0: 0b00101101, 1: 0b10011011}} mem_value_map_zero_extended = [0b0000000000101101, 0b0000000010011011] - 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])): - sim.step({mem_in: i}) - self.assertEqual(sim.inspect(mem_out), mem_value_map_zero_extended[i]) + sim = pyrtl.Simulation(memory_value_map=mem_value_map) + sim.step({mem_addr: 0}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_zero_extended[0]) + sim.step({mem_addr: 1}) + self.assertEqual(sim.inspect(mem_out), mem_value_map_zero_extended[1]) class RTLRomBlockWiring(unittest.TestCase): From 43453ef599d01c45affbbf85af273bca0dadba8c Mon Sep 17 00:00:00 2001 From: Gabor Szita Date: Fri, 17 Jan 2025 15:13:50 -0800 Subject: [PATCH 4/4] Remove unneeded helper method --- tests/test_memblock.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/test_memblock.py b/tests/test_memblock.py index e629da2d..a48bcf2b 100644 --- a/tests/test_memblock.py +++ b/tests/test_memblock.py @@ -274,12 +274,6 @@ def test_memindexed_len(self): self.mem_2 = pyrtl.MemBlock(bitwidth=16, addrwidth=1) self.assertEqual(len(self.mem_2[0]), 16) - def reassemble_bits(bits: list[int]): - value = 0 - for bit in bits: - value = (value << 1) | bit - return value - def test_memindexed_getitem(self): mem = pyrtl.MemBlock(bitwidth=8, addrwidth=1, max_read_ports=None) mem_addr = pyrtl.Input(1, 'mem_addr')