Digital IC hand tearing code-XX company written test questions (serial parallel conversion control)

 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

        The data is serially converted and processed, and 3780 serial bits are input, and each data occupies one clock cycle, and the input occupies a total of 3780 clocks. It is required to output 63 bits in parallel, and a total of 60 clocks are output. The timing diagram is as follows: 1 clock outputs 0, 60,...,3720 in parallel, and outputs the second clock in parallel as 1, 61,... 3721 as the bus as a whole, and the 60th clock outputs 59, 119,... 3779 in parallel Note that each parallel output only occupies one clock cycle , 60 clock cycles will complete the output. The relative delay relationship between output and input can be arbitrary.

problem solving ideas

        This problem seems to be very simple at first glance, and the serial-to-parallel conversion is enough, but it actually involves a single-bit data location problem. Not only that, if the written code is not "one-time", it can withstand back-to-back transmission , and the test of intermittent transmission, the code still needs to be written to take all the circumstances into account.

        Let’s rethink the meaning of the title. The title is to realize a serial-to-parallel conversion, input 1-bit data per cycle, and complete the input of 3780 1-bit data within 3780 cycles. Because the parallel output is performed after all the serial inputs are completed, we need to store 3780 serial inputs, which can be directly stored in RAM or registers. Parallel output, each output 63bit, total output 60 cycles, 60*63bit=3780bit.

        The key here is that the adjacent bits of the parallel output are jumping, 0, 60, 120...; 1, 61, 121...; so it is particularly important to find the mapping relationship between the parallel output and the serial input. A one-dimensional array data_store of 60*63=3780 can be used to store the input serial data. My idea is to use an address addr to index the position stored in the one-dimensional array data_store each time, and then every 63 cycles is a loop, with a total of 60 loops. In one loop, a single bit is written into the one-dimensional array. Data and location are stored in 59, 119, 179,..., 3719, 3779 respectively. Every 63 cycles (after storing 63 bits of data), the one-dimensional array is shifted to the right by 1 bit (high bit on the left, low bit on the right). In this way, after 62 shifts, the first written single-bit data will be shifted to the lowest bit, the bit written at position 62 at the beginning will be shifted to position 0, and the bit written at position 3779 at the beginning , will be shifted to position 3717. Finally, after 60 loops, 3780 single-bit data have been input, and we can output high-bit data, pull the output_valid output valid signal high, and at the same time output 63bit once in a cycle, output 63bit 60 times, and complete the serial to parallel conversion.


reg [5:0] shiftcount;
always @(posedge clk)begin
    if(data_in_ena && loop_row == 6'd0)begin
        data_store[addr] <= serial_data;
    end
    else if(data_in_ena && loop_row != 6'd0 && count_row == 6'd0)begin
        data_store <= {1'b0,data_store[3779:64],serial_data,data_store[62:1]}; //should shift 63 times   60bit shift one times 
        shiftcount <= shiftcount + 1'b1;
    end
    else if(data_in_ena && loop_row != 6'd0 && count_row > 6'd0)begin
        data_store[addr] <= serial_data;
    end
end

always @(posedge clk)begin
    if(!rstn)begin
        addr <= 12'd62;
        shiftcount <= 6'd0;
    end
    else if(data_in_ena && count_row < 59)begin
        addr <= 63*count_row+12'd125;  //addr belongs to {62,125,188,...,3779}  
    end
    else if(data_in_ena && count_row == 59)begin
        addr <= 12'd62;
    end
end

the code

module serial_to_parallel (
    input               clk             ,
    input               rstn            ,
    input               serial_data     ,
    input               data_in_ena     ,

    output      [62:0]  parallel_data   ,
    output  reg         data_out_ena
);

reg [3779:0] data_store;
reg [11:0] addr;
reg [62:0] parallel_data_reg;

reg [5:0] count_column,count_row; //one column is once parallel_data
reg [5:0] loop_column,loop_row;

reg [5:0] output_count;
reg output_valid;

always @(posedge clk)begin     //one loop ,save 63 bits data, so count_column belongs to [0,62]
    if(!rstn)begin
        count_column <= 6'd0;
    end
    else if(data_in_ena && count_column < 6'd62)begin
        count_column <= count_column + 1'b1;
    end
    else if(data_in_ena && count_column == 6'd62)begin
        count_column <= 6'd0;
    end
end

always @(posedge clk)begin     //count_row belongs to [0,59]
    if(!rstn)begin
        count_row <= 6'd0;
    end
    else if(data_in_ena && count_row < 6'd59)begin
        count_row <= count_row + 1'b1;
    end
    else if(data_in_ena && count_row == 6'd59)begin
        count_row <= 6'd0;
    end
end


always @(posedge clk)begin      //loop_column belongs to [0,59]
    if(!rstn)begin
        loop_column <= 6'd0;
    end
    else if(count_column == 6'd62 && loop_column < 6'd59)begin
        loop_column <= loop_column + 1'b1;
    end
    else if(count_column == 6'd62 && loop_column == 6'd59)begin
        loop_column <= 6'd0;
    end
end

always @(posedge clk)begin      //loop_row belongs to [0,62]
    if(!rstn)begin
        loop_row <= 6'd0;
    end
    else if(count_row == 6'd59 && loop_row < 6'd62)begin
        loop_row <= loop_row + 1'b1;
    end
    else if(count_row == 6'd59 && loop_row == 6'd62)begin
        loop_row <= 6'd0;
    end
end


reg [5:0] shiftcount;
always @(posedge clk)begin
    if(data_in_ena && loop_row == 6'd0)begin
        data_store[addr] <= serial_data;
    end
    else if(data_in_ena && loop_row != 6'd0 && count_row == 6'd0)begin
        data_store <= {1'b0,data_store[3779:64],serial_data,data_store[62:1]}; //should shift 63 times   60bit shift one times 
        shiftcount <= shiftcount + 1'b1;
    end
    else if(data_in_ena && loop_row != 6'd0 && count_row > 6'd0)begin
        data_store[addr] <= serial_data;
    end
end

always @(posedge clk)begin
    if(!rstn)begin
        addr <= 12'd62;
        shiftcount <= 6'd0;
    end
    else if(data_in_ena && count_row < 59)begin
        addr <= 63*count_row+12'd125;  //addr belongs to {62,125,188,...,3779}  
    end
    else if(data_in_ena && count_row == 59)begin
        addr <= 12'd62;
    end
end

//parallel output
genvar i ;
generate
    for (i=0;i<=59;i=i+1)begin
        always @(posedge clk)begin
            if(output_valid == 1'b1)begin
                case(output_count)
                    i:parallel_data_reg <= data_store[i*63+62:i*63];
                endcase
            end
        end
    end
endgenerate

always @(posedge clk)begin
    if(!rstn)begin
        output_valid <= 1'b0;
    end
    else if(count_column == 6'd62 && loop_column == 6'd59)begin
        output_valid <= 1'b1;
    end
    else if(output_valid == 1'b1 && output_count == 6'd59)begin
        output_valid <= 1'b0;
    end
end

always @(posedge clk)begin
    if(!rstn)begin
        output_count <= 6'd0;
    end
    else if(output_valid == 1'b1 && output_count < 6'd59)begin
        output_count <= output_count + 1'b1;
    end
    else begin
        output_count <= 6'd0;
    end
end

always @(posedge clk)begin
    data_out_ena <= output_valid; //one beat late
end

assign parallel_data = parallel_data_reg;

endmodule

testbench

module serial_to_parallel_tb();

reg clk,rstn;
reg serial_data,data_in_ena;

wire [62:0] parallel_data;
wire  data_out_ena;

always #5 clk = ~clk;
initial begin
    clk <= 1'd0;
    rstn <= 1'd0;
    serial_data <= 1'b1;
    #16
    rstn <= 1'b1;
    forever begin
        repeat(3780)begin
            #10
            serial_data <= serial_data + 1'b1;
            data_in_ena <= 1'b1;
        end
        repeat(60)begin
            #10
            data_in_ena <= 1'b0;
        end
    end
end
initial begin
    #100000
    $finish();
end

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

serial_to_parallel u_serial_to_parallel(
    .clk            (clk)               ,  
    .rstn           (rstn)              ,
    .serial_data    (serial_data)       ,
    .data_in_ena    (data_in_ena)       ,

    .parallel_data  (parallel_data)     ,
    .data_out_ena   (data_out_ena)
);

endmodule

output waveform

        Back-to-back transmission is supported, single-bit data is input in 3780 cycles, and then a valid signal is input and pulled low for 60 cycles. At this time, the output valid signal is pulled high, and 63-bit parallel data is output for 60 cycles.


 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/127838432