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)
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
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
Use HDL language to realize the interleaver in a way to save chip area. Assume that the input datain order is 1, 2, 3, ... 63, the input enable is datain_ena, and the output order after the interleaver is required to be 1, 10, 19, 28, 37, 46, 55, 2, 11, ...
That is, rows and columns are interleaved, in the order of rows and out in the order of columns, and the input and output data change according to the clock edge. When implementing, you can define ram and use it yourself.
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27
28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54
55 56 57 58 59 60 61 62 63
problem solving ideas
After reading the title, I know that input 64 numbers, save them into a 7*9 matrix, and then output them in columns. To change the meaning of the question, the so-called interleaver in the title here actually realizes the function of transposing a matrix. The matrix input by row is output by column, and data write and read are effectively enabled.
the code
module matrix_trans(
input clk ,
input rstn ,
input [5:0] datain ,
input datain_ena ,
output [5:0] dataout ,
output reg dataout_ena
);
reg [5:0] ram [62:0]; //63 numbers
reg [5:0] addr_wr,addr_rd;
// write data
always @(posedge clk)begin
if(!rstn)begin
addr_wr <= 6'd0;
end
else if(datain_ena && addr_wr < 62)begin
addr_wr <= addr_wr + 1'b1;
end
else if(datain_ena && addr_wr ==62)begin
addr_wr <= 6'd1;
end
end
always @(posedge clk)begin
if(datain_ena)begin
ram[addr_wr] <= datain;
end
end
// read data
always @(posedge clk)begin
if(!rstn)begin
dataout_ena <= 1'b0;
end
else if(addr_rd == 6'd62)begin
dataout_ena <= 1'b0;
end
else if(addr_wr == 6'd62 && datain_ena == 1'b1)begin
dataout_ena <= 1'b1;
end
end
always @(posedge clk)begin
if(!rstn)begin
addr_rd <= 6'd0;
end
else if(dataout_ena==1'b1 && addr_rd < 62)begin
addr_rd <= addr_rd + 1'b1;
end
else if(dataout_ena==1'b1 && addr_rd == 62)begin
addr_rd <= 6'd0;
end
end
// 9*7
// 0=0,1=9,2=18,3=27,4=36,5=45,6=54, 7=1
assign dataout = ram[((addr_rd)%7)*9+addr_rd/7];
endmodule
testbench
module matrix_trans_tb();
reg clk,rstn;
reg [5:0] datain;
reg datain_ena;
wire [5:0] dataout;
wire dataout_ena;
always #5 clk = ~clk;
initial begin
clk <= 1'b0;
rstn <= 1'b0;
#20
rstn <= 1'b1;
#20
datain <= 6'd1;
#20
datain_ena <= 1'b1;
repeat(63)begin
@(posedge clk)begin
datain <= datain + 1'b1;
end
end
datain_ena <= 1'b0;
#2000
$finish();
end
initial begin
forever begin
@(posedge clk)begin
if(dataout_ena == 1'b1)begin
$display("dataout = %d", dataout);
end
end
end
end
//dump fsdb
initial begin
$fsdbDumpfile("matrix_trans.fsdb");
$fsdbDumpvars(0);
end
matrix_trans u_matrix_trans(
.clk (clk) ,
.rstn (rstn) ,
.datain (datain) ,
.datain_ena (datain_ena) ,
.dataout (dataout) ,
.dataout_ena (dataout_ena)
);
endmodule
waveform
We have completed writing 63 numbers in the form of matrix rows, and reading 63 numbers in the form of matrix columns. The read results are shown in the figure:
The output is correct.
For more hand-tearing code questions, you can go to the digital IC hand-tearing code--question bank