def construct(s, nbits=32): dtype = mk_bits(32) xreq_class, xresp_class = mk_xcel_msg(5, nbits) s.xcel = XcelMinionIfcRTL(xreq_class, xresp_class) s.xcelreq_q = NormalQueueRTL(xreq_class, 2) s.xcelreq_q.enq //= s.xcel.req s.xr0 = RegEn(dtype) s.xr0.in_ //= s.xcelreq_q.deq.ret.data @update def up_null_xcel(): if s.xcelreq_q.deq.rdy & s.xcel.resp.rdy: s.xcelreq_q.deq.en @= 1 s.xcel.resp.en @= 1 s.xcel.resp.msg.type_ @= s.xcelreq_q.deq.ret.type_ if s.xcelreq_q.deq.ret.type_ == XcelMsgType.WRITE: s.xr0.en @= 1 s.xcel.resp.msg.data @= 0 else: s.xr0.en @= 0 s.xcel.resp.msg.data @= s.xr0.out else: s.xcelreq_q.deq.en @= 0 s.xcel.resp.en @= 0 s.xr0.en @= 0 s.xcel.resp.msg.data @= 0 s.xcel.resp.msg.type_ @= 0
def construct(s, Type): s.enq = InValRdyIfc(Type) s.deq = OutValRdyIfc(Type) s.buffer = RegEn(Type) s.buffer.in_ //= s.enq.msg s.next_full = Wire(Bits1) s.full = Wire(Bits1) s.byp_mux = m = Mux(Type, 2) m.out //= s.deq.msg m.in_[0] //= s.enq.msg m.in_[1] //= s.buffer.out m.sel //= s.full # full -- buffer.out, empty -- bypass @update_ff def up_full(): s.full <<= s.next_full @update def up_bypq_set_enq_rdy(): s.enq.rdy @= ~s.full @update def up_bypq_internal(): s.buffer.en @= (~s.deq.rdy) & (s.enq.val & s.enq.rdy) s.next_full @= (~s.deq.rdy) & s.deq.val # this enables the sender to make enq.val depend on enq.rdy @update def up_bypq_set_deq_val(): s.deq.val @= s.full | s.enq.val
def construct(s, Type): s.enq = InValRdyIfc(Type) s.deq = OutValRdyIfc(Type) s.buffer = m = RegEn(Type) m.in_ //= s.enq.msg m.out //= s.deq.msg s.next_full = Wire(Bits1) s.full = Wire(Bits1) connect(s.full, s.deq.val) @update_ff def up_full(): s.full <<= s.next_full @update def up_normq_set_enq_rdy(): s.enq.rdy @= ~s.full @update def up_normq_internal(): s.buffer.en @= s.enq.val & s.enq.rdy s.next_full @= (s.full & ~s.deq.rdy) | s.buffer.en
def construct( s, pack_size): #--------------------------------------------------------------------- # Interfaces #--------------------------------------------------------------------- s.recv_from_src = stream.ifcs.RecvIfcRTL(mk_bits(pack_size)) s.send_2master = stream.ifcs.SendIfcRTL(mk_bits(pack_size)) s.recv_from_master = stream.ifcs.RecvIfcRTL(mk_bits(pack_size)) s.send_2sink = stream.ifcs.SendIfcRTL(mk_bits(pack_size)) #--------------------------------------------------------------------- # logic #--------------------------------------------------------------------- @update_ff def src_master(): if (s.state == s.STATE_IDLE): s.cntr <<= 0 elif ((s.cntr >= s.cntr_max) & (s.state != s.STATE_IDLE)): s.cntr <<= 0 else: s.cntr <<= s.cntr + 1 s.recv_from_src.val s.recv_from_src.rdy #--------------------------------------------------------------------- # State Definitions #--------------------------------------------------------------------- s.STATE_RESET = 0 s.STATE_IDLE = 1 s.STATE_HANDSHAKE = 2 s.STATE_TRANSFER = 3 s.STATE_TERMINATION = 4 s.STATE_DONE = 5 s.state = Wire(3) s.cntr = Wire(32) s.cntr_max = Wire(32) s.sclk_en = Wire(1) s.sclk_cntr = Wire(Bits4) #--------------------------------------------------------------------- # State Transition Logic #--------------------------------------------------------------------- @update_ff def state_transitions(): if s.reset: s.state <<= s.STATE_RESET if s.state == s.STATE_RESET: s.state <<= s.STATE_IDLE if s.state == s.STATE_IDLE: if (s.send.rdy & s.recv.val): s.state <<= s.STATE_HANDSHAKE if s.state == s.STATE_HANDSHAKE: if s.cntr >= clk_diff: s.state <<= s.STATE_TRANSFER if s.state == s.STATE_TRANSFER: if s.cntr >= (2*(clk_diff)*(pack_size))-1 : s.state <<= s.STATE_TERMINATION if s.state == s.STATE_TERMINATION: if s.cntr >= clk_diff: s.state <<= s.STATE_DONE if s.state == s.STATE_DONE: # to ensure cs stays high if s.cntr >= clk_diff: s.state <<= s.STATE_IDLE #--------------------------------------------------------------------- # Maximum Counter Value #--------------------------------------------------------------------- @update def max_counter_values(): if s.state == s.STATE_RESET: s.cntr_max @= clk_diff if s.state == s.STATE_IDLE: s.cntr_max @= clk_diff if s.state == s.STATE_HANDSHAKE: s.cntr_max @= clk_diff if s.state == s.STATE_TRANSFER: s.cntr_max @= (2*(clk_diff)*(pack_size))-1 if s.state == s.STATE_TERMINATION: s.cntr_max @= clk_diff if s.state == s.STATE_DONE: s.cntr_max @= clk_diff #--------------------------------------------------------------------- # CS Logic #--------------------------------------------------------------------- @update def cs_logic(): if s.state == s.STATE_RESET: s.master_inter.cs @= 1 if s.state == s.STATE_IDLE: s.master_inter.cs @= 1 if s.state == s.STATE_HANDSHAKE: s.master_inter.cs @= 0 if s.state == s.STATE_TRANSFER: s.master_inter.cs @= 0 if s.state == s.STATE_TERMINATION: s.master_inter.cs @= 0 if s.state == s.STATE_DONE: s.master_inter.cs @= 1 #--------------------------------------------------------------------- # SCLK Logic #--------------------------------------------------------------------- @update def sclk_logic(): if (s.state == s.STATE_TRANSFER): s.sclk_en @= 1 else: s.sclk_en @= 0 #--------------------------------------------------------------------- # Counter Logic #--------------------------------------------------------------------- @update_ff def counter_logic(): if (s.state == s.STATE_IDLE): s.cntr <<= 0 elif ((s.cntr >= s.cntr_max) & (s.state != s.STATE_IDLE)): s.cntr <<= 0 else: s.cntr <<= s.cntr + 1 #--------------------------------------------------------------------- # Generate SCLK #--------------------------------------------------------------------- s.sclk_state = Wire(1) @update_ff def generate_sclk(): if (s.sclk_en): if (s.sclk_cntr == 0): s.master_inter.sclk <<= ~s.master_inter.sclk s.sclk_cntr <<= s.sclk_cntr + 1 elif (s.sclk_cntr == clk_diff-1): s.master_inter.sclk <<= s.master_inter.sclk s.sclk_cntr <<= 0 else: s.master_inter.sclk <<= s.master_inter.sclk s.sclk_cntr <<= s.sclk_cntr + 1 else: s.master_inter.sclk <<= 0 s.sclk_cntr <<= 0 #--------------------------------------------------------------------- # MOSI Datapath #--------------------------------------------------------------------- s.mosi_reg = RegEn( mk_bits(pack_size) ) s.mosi_reg_pointer = Wire ( mk_bits(pack_size) ) s.mosi_reg.in_ //= s.recv.msg @update def mosi_reg_en(): if ((s.state == s.STATE_IDLE) & (s.recv.val == 1)): s.mosi_reg.en @= 1 else: s.mosi_reg.en @= 0 @update def mosi_msb(): s.master_inter.mosi @= s.mosi_reg.out[s.mosi_reg_pointer] @update_ff def mosi_shift_reg(): if s.state == s.STATE_IDLE: s.mosi_reg_pointer <<= pack_size - 1 if s.state == s.STATE_TRANSFER: if (s.master_inter.sclk == 1) & (s.sclk_cntr == 0): if s.mosi_reg_pointer == 0: s.mosi_reg_pointer <<= 0 else: s.mosi_reg_pointer <<= s.mosi_reg_pointer - 1 #--------------------------------------------------------------------- # MISO Datapath #--------------------------------------------------------------------- s.miso_reg = Wire ( mk_bits(pack_size) ) s.miso_reg_pointer = Wire ( mk_bits(pack_size) ) s.send.msg //= s.miso_reg @update_ff def miso_shift_reg(): if s.state == s.STATE_IDLE: s.miso_reg <<= 0 if s.state == s.STATE_TRANSFER: if (s.master_inter.sclk == 0) & (s.sclk_cntr == 0): s.miso_reg <<= concat(s.miso_reg [0:pack_size-1], s.master_inter.miso) #--------------------------------------------------------------------- # val rdy interface #--------------------------------------------------------------------- @update def req_rdy(): s.recv.rdy @= s.send.rdy & (s.state == s.STATE_IDLE) s.result_read = Wire (Bits1) @update def result_read(): #tracks if the result is read or not if s.state == s.STATE_RESET: s.result_read @= 0 if s.state == s.STATE_IDLE: if (s.result_read == 0) & (s.send.rdy == 0): s.result_read @= 0 else: s.result_read @= 1 if s.state == s.STATE_HANDSHAKE: s.result_read @= 0 if s.state == s.STATE_TRANSFER: s.result_read @= 0 if s.state == s.STATE_TERMINATION: s.result_read @= 0 if s.state == s.STATE_DONE: if (s.send.rdy == 1) & (s.cntr > 0): s.result_read @= 1 s.valid_progressing = Wire (Bits1) s.msg_from_minion = Wire (Bits1) @update def valid_resp(): #tracks if response is valid if s.state == s.STATE_RESET: #keeps resp_val low in reset s.valid_progressing @= 0 s.msg_from_minion @= 0 elif ((s.state == s.STATE_IDLE) & (s.recv.val == 1)): s.valid_progressing @= 1 s.msg_from_minion @= 0 elif ((s.state == s.STATE_DONE) & (s.valid_progressing == 1)): s.msg_from_minion @= 1 else: s.valid_progressing @= s.valid_progressing @update def resp_val(): if ((s.state == s.STATE_DONE) & (s.result_read == 0) & (s.msg_from_minion == 1)): s.send.val @= 1 elif ((s.state == s.STATE_IDLE) & (s.result_read == 0) & (s.msg_from_minion == 1)): s.send.val @= 1 else: s.send.val @= 0
def construct(s, pack_size, clk_diff): # clk_diff: SPI signals need to toggle at a frequency slower than the # SPIMinion's ability to sample. With the current design it takes 3 # Minion clk cycles for a signal to be syncronized. A clk_diff of 4 # is the minimum but not recommended. #--------------------------------------------------------------------- # Interfaces #--------------------------------------------------------------------- s.recv = stream.ifcs.RecvIfcRTL(mk_bits(pack_size)) s.send = stream.ifcs.SendIfcRTL(mk_bits(pack_size)) s.master_inter = SPIInterface.MasterInterface() #--------------------------------------------------------------------- # State Definitions #--------------------------------------------------------------------- s.STATE_RESET = 0 s.STATE_IDLE = 1 s.STATE_HANDSHAKE = 2 s.STATE_TRANSFER = 3 s.STATE_TERMINATION = 4 s.STATE_DONE = 5 s.state = Wire(3) s.cntr = Wire(32) s.cntr_max = Wire(32) s.sclk_en = Wire(1) s.sclk_cntr = Wire(Bits4) #--------------------------------------------------------------------- # State Transition Logic #--------------------------------------------------------------------- @update_ff def state_transitions(): if s.reset: s.state <<= s.STATE_RESET if s.state == s.STATE_RESET: s.state <<= s.STATE_IDLE if s.state == s.STATE_IDLE: if (s.send.rdy & s.recv.val): s.state <<= s.STATE_HANDSHAKE if s.state == s.STATE_HANDSHAKE: if s.cntr >= clk_diff: s.state <<= s.STATE_TRANSFER if s.state == s.STATE_TRANSFER: if s.cntr >= (2 * (clk_diff) * (pack_size)) - 1: s.state <<= s.STATE_TERMINATION if s.state == s.STATE_TERMINATION: if s.cntr >= clk_diff: s.state <<= s.STATE_DONE if s.state == s.STATE_DONE: # to ensure cs stays high if s.cntr >= clk_diff: s.state <<= s.STATE_IDLE #--------------------------------------------------------------------- # Maximum Counter Value #--------------------------------------------------------------------- @update def max_counter_values(): if s.state == s.STATE_RESET: s.cntr_max @= clk_diff if s.state == s.STATE_IDLE: s.cntr_max @= clk_diff if s.state == s.STATE_HANDSHAKE: s.cntr_max @= clk_diff if s.state == s.STATE_TRANSFER: s.cntr_max @= (2 * (clk_diff) * (pack_size)) - 1 if s.state == s.STATE_TERMINATION: s.cntr_max @= clk_diff if s.state == s.STATE_DONE: s.cntr_max @= clk_diff #--------------------------------------------------------------------- # CS Logic #--------------------------------------------------------------------- @update def cs_logic(): if s.state == s.STATE_RESET: s.master_inter.cs @= 1 if s.state == s.STATE_IDLE: s.master_inter.cs @= 1 if s.state == s.STATE_HANDSHAKE: s.master_inter.cs @= 0 if s.state == s.STATE_TRANSFER: s.master_inter.cs @= 0 if s.state == s.STATE_TERMINATION: s.master_inter.cs @= 0 if s.state == s.STATE_DONE: s.master_inter.cs @= 1 #--------------------------------------------------------------------- # SCLK Logic #--------------------------------------------------------------------- @update def sclk_logic(): if (s.state == s.STATE_TRANSFER): s.sclk_en @= 1 else: s.sclk_en @= 0 #--------------------------------------------------------------------- # Counter Logic #--------------------------------------------------------------------- @update_ff def counter_logic(): if (s.state == s.STATE_IDLE): s.cntr <<= 0 elif ((s.cntr >= s.cntr_max) & (s.state != s.STATE_IDLE)): s.cntr <<= 0 else: s.cntr <<= s.cntr + 1 #--------------------------------------------------------------------- # Generate SCLK #--------------------------------------------------------------------- s.sclk_state = Wire(1) @update_ff def generate_sclk(): if (s.sclk_en): if (s.sclk_cntr == 0): s.master_inter.sclk <<= ~s.master_inter.sclk s.sclk_cntr <<= s.sclk_cntr + 1 elif (s.sclk_cntr == clk_diff - 1): s.master_inter.sclk <<= s.master_inter.sclk s.sclk_cntr <<= 0 else: s.master_inter.sclk <<= s.master_inter.sclk s.sclk_cntr <<= s.sclk_cntr + 1 else: s.master_inter.sclk <<= 0 s.sclk_cntr <<= 0 #--------------------------------------------------------------------- # MOSI Datapath #--------------------------------------------------------------------- s.mosi_reg = RegEn(mk_bits(pack_size)) s.mosi_reg_pointer = Wire(mk_bits(pack_size)) s.mosi_reg.in_ //= s.recv.msg @update def mosi_reg_en(): if ((s.state == s.STATE_IDLE) & (s.recv.val == 1)): s.mosi_reg.en @= 1 else: s.mosi_reg.en @= 0 @update def mosi_msb(): s.master_inter.mosi @= s.mosi_reg.out[s.mosi_reg_pointer] @update_ff def mosi_shift_reg(): if s.state == s.STATE_IDLE: s.mosi_reg_pointer <<= pack_size - 1 if s.state == s.STATE_TRANSFER: if (s.master_inter.sclk == 1) & (s.sclk_cntr == 0): if s.mosi_reg_pointer == 0: s.mosi_reg_pointer <<= 0 else: s.mosi_reg_pointer <<= s.mosi_reg_pointer - 1 #--------------------------------------------------------------------- # MISO Datapath #--------------------------------------------------------------------- s.miso_reg = Wire(mk_bits(pack_size)) s.miso_reg_pointer = Wire(mk_bits(pack_size)) s.send.msg //= s.miso_reg @update_ff def miso_shift_reg(): if s.state == s.STATE_IDLE: s.miso_reg <<= 0 if s.state == s.STATE_TRANSFER: if (s.master_inter.sclk == 0) & (s.sclk_cntr == 0): s.miso_reg <<= concat(s.miso_reg[0:pack_size - 1], s.master_inter.miso) #--------------------------------------------------------------------- # val rdy interface #--------------------------------------------------------------------- @update def req_rdy(): s.recv.rdy @= s.send.rdy & (s.state == s.STATE_IDLE) s.result_read = Wire(Bits1) @update def result_read(): #tracks if the result is read or not if s.state == s.STATE_RESET: s.result_read @= 0 if s.state == s.STATE_IDLE: if (s.result_read == 0) & (s.send.rdy == 0): s.result_read @= 0 else: s.result_read @= 1 if s.state == s.STATE_HANDSHAKE: s.result_read @= 0 if s.state == s.STATE_TRANSFER: s.result_read @= 0 if s.state == s.STATE_TERMINATION: s.result_read @= 0 if s.state == s.STATE_DONE: if (s.send.rdy == 1) & (s.cntr > 0): s.result_read @= 1 s.valid_progressing = Wire(Bits1) s.msg_from_minion = Wire(Bits1) @update def valid_resp(): #tracks if response is valid if s.state == s.STATE_RESET: #keeps resp_val low in reset s.valid_progressing @= 0 s.msg_from_minion @= 0 elif ((s.state == s.STATE_IDLE) & (s.recv.val == 1)): s.valid_progressing @= 1 s.msg_from_minion @= 0 elif ((s.state == s.STATE_DONE) & (s.valid_progressing == 1)): s.msg_from_minion @= 1 else: s.valid_progressing @= s.valid_progressing @update def resp_val(): if ((s.state == s.STATE_DONE) & (s.result_read == 0) & (s.msg_from_minion == 1)): s.send.val @= 1 elif ((s.state == s.STATE_IDLE) & (s.result_read == 0) & (s.msg_from_minion == 1)): s.send.val @= 1 else: s.send.val @= 0
def construct(s): #--------------------------------------------------------------------- # Interface #--------------------------------------------------------------------- s.req_msg_a = InPort(16) s.req_msg_b = InPort(16) s.resp_msg = OutPort(16) # Control signals (ctrl -> dpath) s.a_mux_sel = InPort(A_MUX_SEL_NBITS) s.a_reg_en = InPort() s.b_mux_sel = InPort(B_MUX_SEL_NBITS) s.b_reg_en = InPort() # Status signals (dpath -> ctrl) s.is_b_zero = OutPort() s.is_a_lt_b = OutPort() #--------------------------------------------------------------------- # Structural composition #--------------------------------------------------------------------- # A mux s.sub_out = Wire(16) s.b_reg_out = Wire(16) s.a_mux = m = Mux(Bits16, 3) m.sel //= s.a_mux_sel m.in_[A_MUX_SEL_IN] //= s.req_msg_a m.in_[A_MUX_SEL_SUB] //= s.sub_out m.in_[A_MUX_SEL_B] //= s.b_reg_out # A register s.a_reg = m = RegEn(Bits16) m.en //= s.a_reg_en m.in_ //= s.a_mux.out # B mux s.b_mux = m = Mux(Bits16, 2) m.sel //= s.b_mux_sel m.in_[B_MUX_SEL_A] //= s.a_reg.out m.in_[B_MUX_SEL_IN] //= s.req_msg_b # B register s.b_reg = m = RegEn(Bits16) m.en //= s.b_reg_en m.in_ //= s.b_mux.out m.out //= s.b_reg_out # Zero compare s.b_zero = m = ZeroComparator(Bits16) m.in_ //= s.b_reg.out m.out //= s.is_b_zero # Less-than comparator s.a_lt_b = m = LTComparator(Bits16) m.in0 //= s.a_reg.out m.in1 //= s.b_reg.out m.out //= s.is_a_lt_b # Subtractor s.sub = m = Subtractor(Bits16) m.in0 //= s.a_reg.out m.in1 //= s.b_reg.out m.out //= s.sub_out # connect to output port s.resp_msg //= s.sub.out