数字IC手撕代码-XX公司笔试真题(交织器/矩阵转置)

 前言:

        本专栏旨在记录高频笔面试手撕代码题,以备数字前端秋招,本专栏所有文章提供原理分析、代码及波形,所有代码均经过本人验证。

目录如下:

1.数字IC手撕代码-分频器(任意偶数分频)

2.数字IC手撕代码-分频器(任意奇数分频)

3.数字IC手撕代码-分频器(任意小数分频)

4.数字IC手撕代码-异步复位同步释放

5.数字IC手撕代码-边沿检测(上升沿、下降沿、双边沿)

6.数字IC手撕代码-序列检测(状态机写法)

7.数字IC手撕代码-序列检测(移位寄存器写法)

8.数字IC手撕代码-半加器、全加器

扫描二维码关注公众号,回复: 15896051 查看本文章

9.数字IC手撕代码-串转并、并转串

10.数字IC手撕代码-数据位宽转换器(宽-窄,窄-宽转换)

11.数字IC手撕代码-有限状态机FSM-饮料机

12.数字IC手撕代码-握手信号(READY-VALID)

13.数字IC手撕代码-流水握手(利用握手解决流水线断流、反压问题)

14.数字IC手撕代码-泰凌微笔试真题

15.数字IC手撕代码-平头哥技术终面手撕真题

16.数字IC手撕代码-兆易创新笔试真题

17.数字IC手撕代码-乐鑫科技笔试真题(4倍频)

18.数字IC手撕代码-双端口RAM(dual-port-RAM)

        ...持续更新

 更多手撕代码题可以前往 数字IC手撕代码--题库


目录

题目描述

解题思路

代码

testbench

波形


题目描述

        用 HDL 语言按照节省芯片面积的方式实现交织器,假定输入的数据 datain 顺序为 1、2、 3、…63,输入使能为 datain_ena,经交织器后输出的顺序要求为 1、10、19、28、37、 46、55、2、11、…

        即行列交织,按行的顺序进按列的顺序出,输入输出数据均按时钟沿变化。实现时可自己 定义 ram 使用。

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

解题思路

        读题意得知,输入64个数,存成一个7*9的矩阵,然后按列输出。把题意转换一下,这里题目中所谓的交织器,其实就是实现一个矩阵转置的功能。把按行输入的矩阵,按列输出,并给出数据写入和读出有效使能。

代码

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

波形

        我们完成了按照矩阵行的形式,写入63个数,按照矩阵列的方式读出63个数,读出结果如图所示:

 输出正确。


 更多手撕代码题可以前往 数字IC手撕代码--题库

猜你喜欢

转载自blog.csdn.net/qq_57502075/article/details/127834190
今日推荐