], name=name, src_loc_at=1)
-class Decoder(Elaboratable):
- """CSR bus decoder.
+class Multiplexer(Elaboratable):
+ """CSR register multiplexer.
An address-based multiplexer for CSR registers implementing atomic updates.
return m
-class Multiplexer(Elaboratable):
- """CSR bus multiplexer.
+class Decoder(Elaboratable):
+ """CSR bus decoder.
- An address-based multiplexer for subordinate CSR buses.
+ An address decoder for subordinate CSR buses.
Usage
-----
Although there is no functional difference between adding a set of registers directly to
- a :class:`Decoder` and adding a set of reigsters to multiple :class:`Decoder`s that are
- aggregated with a :class:`Multiplexer`, hierarchical CSR buses are useful for organizing
- a hierarchical design. If many peripherals are directly served by a single :class:`Decoder`,
- a very large amount of ports will connect the peripheral registers with the decoder, and
- the cost of decoding logic would not be attributed to specific peripherals. With a multiplexer,
- only five signals per peripheral will be used, and the logic could be kept together with
- the peripheral.
+ a :class:`Multiplexer` and adding a set of registers to multiple :class:`Multiplexer`s that are
+ aggregated with a :class:`Decoder`, hierarchical CSR buses are useful for organizing
+ a hierarchical design. If many peripherals are directly served by a single
+ :class:`Multiplexer`, a very large amount of ports will connect the peripheral registers with
+ the decoder, and the cost of decoding logic would not be attributed to specific peripherals.
+ With a decoder, only five signals per peripheral will be used, and the logic could be kept
+ together with the peripheral.
Parameters
----------
def elaborate(self, platform):
m = Module()
- # See Decoder.elaborate above.
+ # See Multiplexer.elaborate above.
r_data_fanin = 0
with m.Switch(self.bus.addr):
Interface(addr_width=16, data_width=-1)
-class DecoderTestCase(unittest.TestCase):
+class MultiplexerTestCase(unittest.TestCase):
def setUp(self):
- self.dut = Decoder(addr_width=16, data_width=8)
+ self.dut = Multiplexer(addr_width=16, data_width=8)
Fragment.get(self.dut, platform=None) # silence UnusedElaboratable
def test_add_4b(self):
sim.run()
-class DecoderAlignedTestCase(unittest.TestCase):
+class MultiplexerAlignedTestCase(unittest.TestCase):
def setUp(self):
- self.dut = Decoder(addr_width=16, data_width=8, alignment=2)
+ self.dut = Multiplexer(addr_width=16, data_width=8, alignment=2)
Fragment.get(self.dut, platform=None) # silence UnusedElaboratable
def test_add_two(self):
sim.run()
-class MultiplexerTestCase(unittest.TestCase):
+class DecoderTestCase(unittest.TestCase):
def setUp(self):
- self.dut = Multiplexer(addr_width=16, data_width=8)
+ self.dut = Decoder(addr_width=16, data_width=8)
Fragment.get(self.dut, platform=None) # silence UnusedElaboratable
def test_add_wrong_sub_bus(self):
self.dut.add(1)
def test_add_wrong_data_width(self):
- decoder = Decoder(addr_width=10, data_width=16)
- Fragment.get(decoder, platform=None) # silence UnusedElaboratable
+ mux = Multiplexer(addr_width=10, data_width=16)
+ Fragment.get(mux, platform=None) # silence UnusedElaboratable
with self.assertRaisesRegex(ValueError,
r"Subordinate bus has data width 16, which is not the same as "
r"multiplexer data width 8"):
- self.dut.add(decoder.bus)
+ self.dut.add(mux.bus)
def test_sim(self):
- dec_1 = Decoder(addr_width=10, data_width=8)
- self.dut.add(dec_1.bus)
+ mux_1 = Multiplexer(addr_width=10, data_width=8)
+ self.dut.add(mux_1.bus)
elem_1 = Element(8, "rw")
- dec_1.add(elem_1)
+ mux_1.add(elem_1)
- dec_2 = Decoder(addr_width=10, data_width=8)
- self.dut.add(dec_2.bus)
+ mux_2 = Multiplexer(addr_width=10, data_width=8)
+ self.dut.add(mux_2.bus)
elem_2 = Element(8, "rw")
- dec_2.add(elem_2, addr=2)
+ mux_2.add(elem_2, addr=2)
elem_1_addr, _, _ = self.dut.bus.memory_map.find_resource(elem_1)
elem_2_addr, _, _ = self.dut.bus.memory_map.find_resource(elem_2)
self.assertEqual((yield bus.r_data), 0xaa)
m = Module()
- m.submodules += self.dut, dec_1, dec_2
+ m.submodules += self.dut, mux_1, mux_2
with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
sim.add_clock(1e-6)
sim.add_sync_process(sim_test())