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()
Exemplo n.º 2
0
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()