frontend/ecc: add ecc adapter
This commit is contained in:
parent
c84b58735a
commit
461b076624
|
@ -140,3 +140,58 @@ class ECCDecoder(SECDEC, Module):
|
|||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class LiteDRAMNativePortECC(Module):
|
||||
def __init__(self, port_from, port_to):
|
||||
_ , n = compute_m_n(port_from.data_width//8)
|
||||
assert port_to.data_width >= n + 1
|
||||
|
||||
self.clear_errors = clear_errors = Signal()
|
||||
self.sec_errors = sec_errors = Signal(32)
|
||||
self.dec_errors = dec_errors = Signal(32)
|
||||
|
||||
# # #
|
||||
|
||||
# cmd
|
||||
self.comb += port_from.cmd.connect(port_to.cmd)
|
||||
|
||||
# wdata (ecc encoding)
|
||||
for i in range(8):
|
||||
encoder = ECCEncoder(port_from.data_width//8)
|
||||
self.submodules += encoder
|
||||
self.comb += [
|
||||
port_from.wdata.connect(port_to.wdata, omit={"data", "we"}),
|
||||
encoder.i.eq(port_from.wdata.data[i*port_from.data_width//8:(i+1)*port_from.data_width//8]),
|
||||
port_to.wdata.data[i*port_to.data_width//8:(i+1)*port_to.data_width//8].eq(encoder.o)
|
||||
]
|
||||
self.comb += port_to.wdata.we.eq(2**len(port_to.wdata.we)-1) # FIXME: how to handle we?
|
||||
|
||||
# rdata (ecc decoding)
|
||||
sec = Signal(8)
|
||||
dec = Signal(8)
|
||||
for i in range(8):
|
||||
decoder = ECCDecoder(port_from.data_width//8)
|
||||
self.submodules += decoder
|
||||
self.comb += [
|
||||
port_to.rdata.connect(port_from.rdata, omit={"data", "we"}),
|
||||
decoder.i.eq(port_to.rdata.data[i*port_to.data_width//8:(i+1)*port_to.data_width//8]),
|
||||
port_from.rdata.data[i*port_from.data_width//8:(i+1)*port_from.data_width//8].eq(decoder.o),
|
||||
sec[i].eq(decoder.sec),
|
||||
dec[i].eq(decoder.dec)
|
||||
]
|
||||
|
||||
# errors count
|
||||
self.sync += [
|
||||
If(clear_errors,
|
||||
sec_errors.eq(0),
|
||||
dec_errors.eq(0)
|
||||
).Else(
|
||||
If(sec_errors != (2**len(sec_errors) - 1),
|
||||
If(sec != 0, sec_errors.eq(sec_errors + 1))
|
||||
),
|
||||
If(dec_errors != (2**len(dec_errors) - 1),
|
||||
If(dec != 0, dec_errors.eq(dec_errors + 1))
|
||||
)
|
||||
)
|
||||
]
|
||||
|
|
|
@ -3,6 +3,7 @@ import random
|
|||
|
||||
from migen import *
|
||||
|
||||
from litedram.common import *
|
||||
from litedram.frontend.ecc import *
|
||||
|
||||
from litex.gen.sim import *
|
||||
|
@ -93,3 +94,14 @@ class TestECC(unittest.TestCase):
|
|||
dut = DUT(k)
|
||||
run_simulation(dut, generator(dut, k, 128, i))
|
||||
self.assertEqual(dut.errors, 0)
|
||||
|
||||
def test_ecc_wrapper(self):
|
||||
# 32 bits + 8 bits ecc
|
||||
port_from = LiteDRAMNativePort("both", 24, 32*8)
|
||||
port_to = LiteDRAMNativePort("both", 24, 40*8)
|
||||
ecc = LiteDRAMNativePortECC(port_from, port_to)
|
||||
|
||||
# 64 bits + 8 bits ecc
|
||||
port_from = LiteDRAMNativePort("both", 24, 64*8)
|
||||
port_to = LiteDRAMNativePort("both", 24, 72*8)
|
||||
ecc = LiteDRAMNativePortECC(port_from, port_to)
|
||||
|
|
Loading…
Reference in New Issue