from lib.sata.common import *
from lib.sata.link.scrambler import Scrambler
-@DecorateModule(InsertReset)
-@DecorateModule(InsertCE)
-class Counter(Module):
- def __init__(self, width, signal=None, reset=0):
- if signal is None:
- self.value = Signal(width, reset=reset)
- else:
- self.value = signal
- self.sync += self.value.eq(self.value+1)
-
class SATABIST(Module):
def __init__(self, sector_size=512, max_count=1):
self.sink = sink = Sink(command_rx_description(32))
self.ctrl_errors = Signal(32)
self.data_errors = Signal(32)
-
- counter = Counter(32)
- ctrl_error_counter = Counter(32, self.ctrl_errors)
- data_error_counter = Counter(32, self.data_errors)
+ counter = Counter(bits_sign=32)
+ ctrl_error_counter = Counter(self.ctrl_errors, bits_sign=32)
+ data_error_counter = Counter(self.data_errors, bits_sign=32)
self.submodules += counter, data_error_counter, ctrl_error_counter
scrambler = InsertReset(Scrambler())
layout = [
("data", dw)
]
- return EndpointDescription(layout, packetized=True)
\ No newline at end of file
+ return EndpointDescription(layout, packetized=True)
+
+@DecorateModule(InsertReset)
+@DecorateModule(InsertCE)
+class Counter(Module):
+ def __init__(self, signal=None, **kwargs):
+ if signal is None:
+ self.value = Signal(**kwargs)
+ else:
+ self.value = signal
+ self.width = flen(self.value)
+ self.sync += self.value.eq(self.value+1)
# Detect consecutive primitives
# tn insert CONT
- cnt = Signal(2)
+ counter = Counter(max=4)
+ self.submodules += counter
+
is_primitive = Signal()
last_was_primitive = Signal()
last_primitive = Signal(32)
self.comb += [
is_primitive.eq(sink.charisk != 0),
change.eq((sink.data != last_primitive) | ~is_primitive),
- cont_insert.eq(~change & (cnt==1)),
- scrambler_insert.eq(~change & (cnt==2)),
- last_primitive_insert.eq((cnt==2) & (
+ cont_insert.eq(~change & (counter.value == 1)),
+ scrambler_insert.eq(~change & (counter.value == 2)),
+ last_primitive_insert.eq((counter.value == 2) & (
(~is_primitive & last_was_primitive) |
(is_primitive & (last_primitive == primitives["HOLD"]) & (last_primitive != sink.data))))
]
last_was_primitive.eq(0)
),
If(change | last_primitive_insert_d,
- cnt.eq(0)
+ counter.reset.eq(1)
).Else(
- If(~scrambler_insert,
- cnt.eq(cnt+1)
- )
+ counter.ce.eq(~scrambler_insert)
)
)
cmd_ndwords = max(fis_reg_h2d_cmd_len, fis_data_cmd_len)
encoded_cmd = Signal(cmd_ndwords*32)
- cnt = Signal(max=cmd_ndwords+1)
- clr_cnt = Signal()
- inc_cnt = Signal()
+ counter = Counter(max=cmd_ndwords+1)
+ self.submodules += counter
- cmd_len = Signal(flen(cnt))
+ cmd_len = Signal(counter.width)
cmd_with_data = Signal()
cmd_send = Signal()
self.submodules += fsm
fsm.act("IDLE",
- clr_cnt.eq(1),
+ counter.reset.eq(1),
If(sink.stb & sink.sop,
If(test_type("REG_H2D"),
NextState("SEND_REG_H2D_CMD")
self.comb += \
If(cmd_send,
link.sink.stb.eq(sink.stb),
- link.sink.sop.eq(cnt==0),
- link.sink.eop.eq((cnt==cmd_len) & ~cmd_with_data),
- Case(cnt, cmd_cases),
- inc_cnt.eq(sink.stb & link.sink.ack),
- cmd_done.eq((cnt==cmd_len) & link.sink.stb & link.sink.ack)
+ link.sink.sop.eq(counter.value == 0),
+ link.sink.eop.eq((counter.value == cmd_len) & ~cmd_with_data),
+ Case(counter.value, cmd_cases),
+ counter.ce.eq(sink.stb & link.sink.ack),
+ cmd_done.eq((counter.value == cmd_len) & link.sink.stb & link.sink.ack)
).Elif(data_send,
link.sink.stb.eq(sink.stb),
link.sink.sop.eq(0),
link.sink.d.eq(sink.data),
)
- self.sync += \
- If(clr_cnt,
- cnt.eq(0)
- ).Elif(inc_cnt,
- cnt.eq(cnt+1)
- )
-
def _decode_cmd(signal, description, obj):
r = []
for k, v in sorted(description.items()):
cmd_ndwords = max(fis_reg_d2h_cmd_len, fis_dma_activate_d2h_cmd_len, fis_data_cmd_len)
encoded_cmd = Signal(cmd_ndwords*32)
- cnt = Signal(max=cmd_ndwords+1)
- clr_cnt = Signal()
- inc_cnt = Signal()
+ counter = Counter(max=cmd_ndwords+1)
+ self.submodules += counter
- cmd_len = Signal(flen(cnt))
+ cmd_len = Signal(counter.width)
cmd_receive = Signal()
data_receive = Signal()
data_sop = Signal()
fsm.act("IDLE",
- clr_cnt.eq(1),
+ counter.reset.eq(1),
If(link.source.stb & link.source.sop,
If(test_type("REG_D2H"),
NextState("RECEIVE_REG_D2H_CMD")
cmd_cases[i] = [encoded_cmd[32*i:32*(i+1)].eq(link.source.d)]
self.comb += \
- If(cmd_receive,
- If(link.source.stb,
- inc_cnt.eq(1),
- ).Else(
- inc_cnt.eq(0)
- )
+ If(cmd_receive & link.source.stb,
+ counter.ce.eq(1)
)
self.sync += \
If(cmd_receive,
- Case(cnt, cmd_cases),
- )
- self.sync += \
- If(clr_cnt,
- cnt.eq(0)
- ).Elif(inc_cnt,
- cnt.eq(cnt+1)
+ Case(counter.value, cmd_cases),
)
- self.comb += cmd_done.eq((cnt==cmd_len) & link.source.ack)
+ self.comb += cmd_done.eq((counter.value == cmd_len) & link.source.ack)
self.comb += link.source.ack.eq(cmd_receive | (data_receive & source.ack))
class SATATransport(Module):