diff --git a/skidbuffer.py b/skidbuffer.py index 99a3196707d16888bae906710722fa9b5f54d5be..2f841740f536c22e54e6c9a0b898525405abb0a4 100644 --- a/skidbuffer.py +++ b/skidbuffer.py @@ -2,7 +2,7 @@ from nmigen import * from nmigen.cli import main -class SkidBuffer(Elaboratable): # non-registered +class NonRegisteredSkidBuffer(Elaboratable): # non-registered def __init__(self, width): self.width = width @@ -59,6 +59,10 @@ class SkidBuffer(Elaboratable): # non-registered return m + + + + class DummyPlug(Elaboratable): def elaborate(self, platform): m = Module() diff --git a/stack.py b/stack.py index b68a924beead605979cd0750845195d58634afdf..3f4c3a11dab65133210f617af7e97c148e3866be 100644 --- a/stack.py +++ b/stack.py @@ -5,6 +5,8 @@ from nmigen_boards.ice40_hx8k_b_evn import * from functools import reduce +from skidbuffer import NonRegisteredSkidBuffer + class InspectableRegister(Elaboratable): def __init__(self, width): self.width = width @@ -236,25 +238,27 @@ class MasterStateMachine(Elaboratable): self.execute_rules = execute_rules self.data_in = Signal(item_width) + + self.data_in_valid = Signal(1) self.data_in_ready = Signal(1) self.data_out = Signal(item_width) - def elaborate(self, platform): - - new_item = Signal(self.item_width) - - - - number_to_pop = Signal(8) + def elaborate(self, platform): m = Module() stack = InspectableStack(item_width=self.item_width, stack_depth=self.stack_depth) rule_matcher = HitOrMiss(item_width=self.item_width, stack_depth=self.stack_depth, ruleset = self.match_rules) rex = RuleExecutor(item_width=self.item_width, stack_depth=self.stack_depth, execution_ruleset=self.execute_rules) + skbuffer = NonRegisteredSkidBuffer(width = self.item_width) m.submodules.Stack = stack m.submodules.RuleMatcher = rule_matcher m.submodules.RuleExecute = rex + m.submodules.skidbuffer = skbuffer + + new_item = Signal(self.item_width) + number_to_pop = Signal(8) + m.d.comb += rex.match_index_in.eq(rule_matcher.match_index_out) @@ -264,37 +268,31 @@ class MasterStateMachine(Elaboratable): # Skid buffer - - skidbuffer = Signal(self.item_width) - skid_occupied = Signal(1) fsm_ready = Signal(1) - + fsm_data_valid = Signal(1) fsm_data = Signal(self.item_width) - with m.If(fsm_ready == 1): # FSM can accept - with m.If(skid_occupied == 1): # skidbuffer occupied - m.d.sync += fsm_data.eq(skidbuffer) # drain the skidbuffer - m.d.sync += skid_occupied.eq(0) - m.d.sync += self.data_in_ready.eq(0) + m.d.comb += skbuffer.upstream_valid_in.eq(self.data_in_valid) + m.d.comb += self.data_in_ready.eq(skbuffer.upstream_ready_out) + m.d.comb += skbuffer.upstream_data_in.eq(self.data_in) + m.d.comb += skbuffer.downstream_ready_in.eq(fsm_ready) + m.d.comb += fsm_data.eq(skbuffer.downstream_data_out) + m.d.comb += fsm_data_valid.eq(skbuffer.downstream_valid_out) - with m.If(skid_occupied == 0): # skidbuffer empty - m.d.sync += fsm_data.eq(self.data_in) # just wire them together - m.d.sync += self.data_in_ready.eq(1) # and we're open for business - with m.If(fsm_ready == 0): # FSM cannot accept data - with m.If(skid_occupied == 0): - m.d.sync += skidbuffer.eq(self.data_in) # capture the data - m.d.sync += skid_occupied.eq(1) - m.d.sync += self.data_in_ready.eq(0) # LR parser state machine with m.FSM() as fsm: with m.State("SHIFT"): - m.d.comb += stack.command_in.eq(2) - m.d.comb += stack.command_in_strobe.eq(1) - m.d.comb += stack.push_port.eq(fsm_data) - m.d.comb += fsm_ready.eq(1) + m.d.comb += stack.command_in_strobe.eq(0) + + + with m.If(fsm_data_valid == 1): + m.d.comb += stack.command_in.eq(2) + m.d.comb += stack.command_in_strobe.eq(1) + m.d.comb += stack.push_port.eq(fsm_data) + m.d.comb += fsm_ready.eq(1) with m.If(rule_matcher.match_index_out != 0): # start poppin' @@ -335,7 +333,7 @@ class DummyPlug(Elaboratable): cntr = Signal(8) m = Module() - mem = Memory(width=16, depth=256, init=[0x000,0xfa00,0xfa00,0xfa00,0xfe42,0xfb00,0xfb00,0xfb00]) + mem = Memory(width=16, depth=256, init=[0x00,0xfa00,0xfa00,0xfa00,0xfe42,0xfb00,0xfb00,0xfb00]) m.submodules.parse_data = rdport = mem.read_port() msm = MasterStateMachine(item_width=16, stack_depth=8, match_rules=[[(0,0xffff,0xfb00), (1,0xff00, 0xfe00), (2,0xffff,0xfa00)]], execute_rules=[(2,0xfe00,(lambda stackview: 0xfe00 + (stackview[1] & 0x00ff)))]) @@ -343,6 +341,7 @@ class DummyPlug(Elaboratable): with m.If(msm.data_in_ready == 1): m.d.sync += cntr.eq(cntr + 1) + m.d.comb += msm.data_in_valid.eq(1) m.d.comb += (rdport).addr.eq(cntr) m.d.comb += (msm.data_in).eq((rdport).data)