Digital IC hand tearing code-XX company written test questions (summation of data flow pipeline)

 Foreword: 

        This column aims to record high-frequency pen interview hand-torn code questions for digital front-end autumn recruits. All articles in this column provide principle analysis, codes and waveforms, and all codes have been verified by myself.

The directory is as follows:

1. Digital IC hand-tear code-frequency divider (any even number frequency division)

2. Digital IC hand-tear code-frequency divider (any odd frequency division)

3. Digital IC hand-tear code-frequency divider (any decimal frequency division)

4. Digital IC hand tearing code - asynchronous reset and synchronous release

5. Digital IC hand tear code - edge detection (rising edge, falling edge, double edge)

6. Digital IC hand tearing code-sequence detection (state machine writing method)

7. Digital IC hand tearing code-sequence detection (shift register writing method)

8. Digital IC tearing code - half adder, full adder

9. Digital IC hand tearing code - serial to parallel, parallel to serial

10. Digital IC hand tearing code-data bit width converter (width-narrow, narrow-width conversion)

11. Digital IC hand tearing code - finite state machine FSM - beverage machine

12. Digital IC hand tear code - handshake signal (READY-VALID)

13. Digital IC hand tearing code - water handshake (use handshake to solve the problem of pipeline interruption and back pressure)

14. Digital IC hand tearing code - Telink micro written test questions

15. Digital IC hand tearing code - Pingtouge technology final face hand tearing real question

16. Digital IC manual tearing code-Zhaoyi innovation written test real questions

17. Digital IC hand tearing code - Espressif Technology written test real questions (4 times frequency)

18. Digital IC tearing code - dual-port RAM (dual-port-RAM)

        ...Continually updated

 For more hand-tearing code questions, you can go to  the digital IC hand-tearing code--question bank


Table of contents

topic description

problem solving ideas

the code

testbench

output waveform


topic description

        Input continuous data streams to get the sum value of every 256 data streams. The timing diagram is as follows:

        The input is i0, i1, i2,…, i253, i254,….accounting for 1 clock cycle, the output sum0 is the sum value of i0 +i2+….+i254 (addition at intervals), and sum1 is i1+i3+…. +i255, sum2 is i2+i4+….+i256, and so on, each output occupies one clock cycle, and the relative delay relationship between Sum0 and i0 is arbitrary. Assuming that the input i0, i1, i254, ... are 8-bit values, and the output sum please choose a suitable bit width that will not lose precision, and use the verilog language to achieve the above requirements in the most resource-saving way you think.

problem solving ideas

        The summation of this question is actually relatively simple, but the key is to use the most resource-efficient way to achieve the requirements. All inputs are 8bit, sum0 plus sum1 is from i0 to i255, and 256 8bit numbers are added. Therefore, the addition of 256 8-bit numbers needs to be represented by 16-bit numbers, so set the sum to 15 bits. And there are rules:

        sum2=sum0-i0+i256,sum3=sum1-i1+i257

        You can use a space datain_store with a depth of 257*8bit bits to store i0-i256, and then every time a value is entered, datain_store will shift 8bit to store the new incoming number. Then use two sums, one sum outputs the sum of odd 128 items, and one sum outputs the sum of even 128 items.

the code

module pip_sum(
    input           clk         ,
    input           rstn        ,
    input  [7:0]    datain      ,
    input           datain_ena  ,
    
    output [14:0]   sum         ,
    output          dataout_ena 
);

reg [8*257-1:0] datain_store;  //DEPTH = 2056

reg [7:0] count;
reg [14:0] sum_odd,sum_even;

reg datain_ena_onebeat;

reg flag;

always @(posedge clk)begin
    if(datain_ena)begin
        datain_store <= {datain_store[8*256-1:0],datain}; //left shift 8bit, store datain in low 8bit
    end
end

always @(posedge clk)begin
    if(!rstn)begin
        count <= 8'd0;
    end
    else if(datain_ena_onebeat == 1'b1 && count < 8'd255)begin
        count <= count + 1'b1;
    end
    else if(datain_ena_onebeat == 1'b1 && count == 8'd255)begin
        count <= 8'd0;
    end
end

always @(posedge clk)begin
    if(!rstn)
        flag <= 1'b0;
    else if(count == 8'd255) 
        flag <= 1'b1;  //
end
wire [7:0] look;
assign look = datain_store[7:0];
always @(posedge clk)begin
    if(!rstn)begin
        sum_odd  <= 15'd0;
        sum_even <= 15'd0;
    end
    else begin
        datain_ena_onebeat <= datain_ena;
        if(datain_ena_onebeat) 
            case(count[0])
                0:begin 
                    if(flag==0)
                        sum_even <= sum_even + datain_store[7:0];
                    else 
                        sum_even <= sum_even - datain_store[8*257-1:8*256] + datain_store[7:0];
                end
                1:begin
                    if(flag==0)
                        sum_odd  <= sum_odd  + datain_store[7:0];
                    else 
                        sum_odd  <= sum_odd - datain_store[8*257-1:8*256] + datain_store[7:0];
                end
            endcase
    end
end

reg [14:0] sum_odd_onebeat,sum_even_onebeat;
always @(posedge clk)begin
    sum_odd_onebeat  <= sum_odd;
    sum_even_onebeat <= sum_even;
end

assign sum = (count[0]) ? sum_odd_onebeat: sum_even_onebeat;
assign dataout_ena = flag;

endmodule

testbench

module pip_sum_tb();

reg clk,rstn;
reg [15:0] count;
reg [7:0] datain;
reg datain_ena;

wire [14:0] sum;
wire dataout_ena;

always #5 clk <= ~clk;
initial begin
    clk <= 1'b0;
    rstn <= 1'b0;
    #16
    rstn <= 1'b1;
    #20
    datain_ena <= 1'b1;

    #10000
    $finish();
end

initial begin
    datain <= 8'd0;
    count <= 1'b0;
    forever begin
        @(posedge clk)begin
            if(datain_ena == 1)begin
                if(count < 255)begin
                    datain <= 1'b0;
                end
                else
                    datain <= datain + 1'b1;
                    count <= count + 1'b1;
            end
        end
    end
end

//dump fsdb
initial begin
    $fsdbDumpfile("pip_sum.fsdb");
    $fsdbDumpvars(0);
end

pip_sum u_pip_sum(
    .clk            (clk)       ,
    .rstn           (rstn)      ,
    .datain         (datain)    ,
    .datain_ena     (datain_ena),

    .sum            (sum)       ,
    .dataout_ena    (dataout_ena)
);

endmodule

output waveform

        For the convenience of checking the correctness of the results, let the first 256 cycles of datain be 0, so that the output sum0 and sum1 are both 0, and then let datain increment as a positive integer sequence. As can be seen from the output results, it is consistent with our expectations, sum0=sum1=0, sum2=sum0-i0+i256=0-0+1=1; sum3=sum1-i1+i257=0-0+2=2, and so on.


 For more hand-tearing code questions, you can go to  the digital IC hand-tearing code--question bank

Guess you like

Origin blog.csdn.net/qq_57502075/article/details/127836194