def arithmetic_mean4(rst, clk, rx_rdy, rx_vld, rx_dat, tx_rdy, tx_vld, tx_dat): ''' Calculates the arithmetic mean of every 4 consecutive input numbers Input handshake & data rx_rdy - (o) Ready rx_vld - (i) Valid rx_dat - (i) Data Output handshake & data tx_rdy - (i) Ready tx_vld - (o) Valid tx_dat - (o) Data Implementation: 3-stage pipeline stage 0: registers input data stage 1: sum each 4 consecutive numbers and produce the sum as a single result stage 2: divide the sum by 4 Each stage is implemented as a separate process controlled by a central pipeline control unit via an enable signal The pipeline control unit manages the handshake and synchronizes the operation of the stages ''' DATA_WIDTH = len(rx_dat) NUM_STAGES = 3 stage_en = Signal(intbv(0)[NUM_STAGES:]) stop_tx = Signal(intbv(0)[NUM_STAGES:]) pipe_ctrl = pipeline_control( rst = rst, clk = clk, rx_vld = rx_vld, rx_rdy = rx_rdy, tx_vld = tx_vld, tx_rdy = tx_rdy, stage_enable = stage_en, stop_tx = stop_tx) s0_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_0(): ''' Register input data''' if (stage_en[0]): s0_dat.next = rx_dat s1_sum = Signal(intbv(0)[DATA_WIDTH+2:]) s1_cnt = Signal(intbv(0, min=0, max=4)) @always(clk.posedge) def stage_1(): ''' Sum each 4 consecutive data''' if (rst): s1_cnt.next = 0 stop_tx.next[1] = 1 elif (stage_en[1]): # Count input data s1_cnt.next = (s1_cnt + 1) % 4 if (s1_cnt == 0): s1_sum.next = s0_dat else: s1_sum.next = s1_sum.next + s0_dat # Produce result only after data 0, 1, 2, and 3 have been summed if (s1_cnt == 3): stop_tx.next[1] = 0 else: stop_tx.next[1] = 1 ''' stop_tx[1] concerns the data currently registered in stage 1 - it determines whether the data will be sent to the next pipeline stage (stop_tx==0) or will be dropped (stop_tx==1 ). The signals stop_rx and stop_tx must be registered ''' s2_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_2(): ''' Divide by 4''' if (stage_en[2]): s2_dat.next = s1_sum // 4 @always_comb def comb(): tx_dat.next = s2_dat return instances()
def twos_complement(rst, clk, rx_rdy, rx_vld, rx_dat, tx_rdy, tx_vld, tx_dat): ''' Two's complement conversion of a binary number Input handshake & data rx_rdy - (o) Ready rx_vld - (i) Valid rx_dat - (i) Data Output handshake & data tx_rdy - (i) Ready tx_vld - (o) Valid tx_dat - (o) Data Implementation: 3-stage pipeline stage 0: registers input data stage 1: inverts data coming from stage 0 and registers the inverted data stage 2: increments data coming from stage 1 and registers the incremented data Each stage is implemented as a separate process controlled by a central pipeline control unit via an enable signal The pipeline control unit manages the handshake and synchronizes the operation of the stages ''' DATA_WIDTH = len(rx_dat) NUM_STAGES = 3 stage_en = Signal(intbv(0)[NUM_STAGES:]) pipe_ctrl = pipeline_control( rst = rst, clk = clk, rx_vld = rx_vld, rx_rdy = rx_rdy, tx_vld = tx_vld, tx_rdy = tx_rdy, stage_enable = stage_en) s0_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_0(): ''' Register input data''' if (stage_en[0]): s0_dat.next = rx_dat s1_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_1(): ''' Invert data''' if (stage_en[1]): s1_dat.next = ~s0_dat s2_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_2(): ''' Add one to data''' if (stage_en[2]): s2_dat.next = s1_dat + 1 @always_comb def comb(): tx_dat.next = s2_dat.signed() return instances()
def sequence4(rst, clk, rx_rdy, rx_vld, rx_dat, tx_rdy, tx_vld, tx_dat): ''' For every received input data A generates a sequence of 4 output data 2*A, 2*(A+1), 2*(A+2), 2*(A+3) Input handshake & data rx_rdy - (o) Ready rx_vld - (i) Valid rx_dat - (i) Data Output handshake & data tx_rdy - (i) Ready tx_vld - (o) Valid tx_dat - (o) Data Implementation: 3-stage pipeline stage 0: registers input data stage 1: increments the data 4 times stage 2: multiplies by 2 Each stage is implemented as a separate process controlled by a central pipeline control unit via an enable signal The pipeline control unit manages the handshake and synchronizes the operation of the stages ''' DATA_WIDTH = len(rx_dat) NUM_STAGES = 3 stage_en = Signal(intbv(0)[NUM_STAGES:]) stop_rx = Signal(intbv(0)[NUM_STAGES:]) pipe_ctrl = pipeline_control( rst = rst, clk = clk, rx_vld = rx_vld, rx_rdy = rx_rdy, tx_vld = tx_vld, tx_rdy = tx_rdy, stage_enable = stage_en, stop_rx = stop_rx) s0_dat = Signal(intbv(0)[DATA_WIDTH:]) @always_seq(clk.posedge, reset=rst) def stage_0(): ''' Register input data''' if (stage_en[0]): s0_dat.next = rx_dat s1_sum = Signal(intbv(0)[DATA_WIDTH+1:]) s1_cnt = Signal(intbv(0, min=0, max=4)) @always(clk.posedge) def stage_1(): ''' Increment data''' if (rst): s1_cnt.next = 0 stop_rx.next[1] = 0 elif (stage_en[1]): # Count output data s1_cnt.next = (s1_cnt + 1) % 4 if (s1_cnt == 0): s1_sum.next = s0_dat else: s1_sum.next = s1_sum.next + 1 # Consume input data only after output data 0, 1, 2, and 3 have been produced if (s1_cnt == 3): stop_rx.next[1] = 0 else: stop_rx.next[1] = 1 ''' stop_rx[1] concerns the next data to be consumed by stage 1 - it determines whether a data will be taken from the previous pipeline stage (stop_rx==0) or no data will be taken (stop_rx==1 ). The signals stop_rx and stop_tx must be registered ''' s2_dat = Signal(intbv(0)[DATA_WIDTH+2:]) @always_seq(clk.posedge, reset=rst) def stage_2(): ''' Multiply by 2''' if (stage_en[2]): s2_dat.next = s1_sum * 2 @always_comb def comb(): tx_dat.next = s2_dat return instances()