今天继续为大家解析联发科技数字IC设计岗的笔试题。
14、【简答题】设计一个“1011”或“1110”串行序列的检测器(两种序列需同时检测),画出状态转换图,并用HDL语言实现这个状态机(15分)解析:本题目主要考察了状态机的相关知识本题是一道常规的序列检测类状态机题目,不同的是需要检测两个序列。序列检测一般分为可重叠检测和不可重叠检测,本题我们就基于可重叠检测来解析。状态转换图如下所示:HDL代码如下所示:
//-------------------
01 module fsm(
02 inputwireclk,
03 inputwire rst_n,
04 inputwiredin,
05
06 outputregdout
07 );
08
09 parameter S0 = 5'b00001;
10 parameter S1 = 5'b00010;
11 parameter S2 = 5'b00100;
12 parameter S3 = 5'b01000;
13 parameter S4 = 5'b10000;
14
15 reg [4:0] state;
16
17 //第一段状态机
18 always@(posedge clk or negedge rst_n)
19 if(!rst_n)
20 state <= S0;
21 else case(state)
22 S0:if(din == 1'b1)
23 state <= S1;
24 else
25 state <= S0;
26 S1:if(din == 1'b1)
27 state <= S2;
28 else
29 state <= S0;
30 S2:if(din == 1'b1)
31 state <= S4;
32 else
33 state <= S3;
34 S3:if(din == 1'b1)
35 state <= S1;
36 else
37 state <= S0;
38 S4:if(din == 1'b1)
39 state <= S4;
40 else
41 state <= S3;
42 default:state <= S0;
43 endcase
44
45 //第二段状态机
46 always@(posedge clk or negedge rst_n)
47 if(!rst_n)
48 dout <= 1'b0;
49 elseif((state == S3 && din == 1'b1) || (state == S4 && din == 1'b0))
50 dout <= 1'b1;
51 else
52 dout <= 1'b0;
53
54 endmodule
//------------------用QuartusII综合后的状态转移图如下所示:Testbench如下所示://------------01 moduletb_fsm();02 03 regclk;04 regrst_n;05 regdin;06 07 wiredout;08 09 //初始化系统时钟、全局复位10 initialbegin11 clk = 1'b1;12 rst_n <= 1'b0;13 #2014 rst_n <= 1'b1;15 #100016 $finish;17 end18 19 always#10clk = ~clk;20 21 //产生din的非负随机数22 always@(posedge clk or negedge rst_n)23 if(!rst_n)24 din <= 1'b0;25 else26 din <= {$random} % 2;27 28 //-------------29 //在QuestaSim仿真时让波形显示状态机的名字30 //--------------31 parameter S0 = 5'b00001;32 parameter S1 = 5'b00010;33 parameter S2 = 5'b00100;34 parameter S3 = 5'b01000;35 parameter S4 = 5'b10000;36 37 wire [4:0] state = fsm_inst.state; //将RTL模块中的内部信号引入到Testbench模块中来38 reg [15:0] state_name;//1个字符8位宽,这里我们要显示的最长的字符为“S0”2个字符,所以需要16位39 40 //state_name:状态对应状态变量名41 always@(*)42 case(state)43 S0 : state_name = "S0";44 S1 : state_name = "S1";45 S2 : state_name = "S2";46 S3 : state_name = "S3";47 S4 : state_name = "S4";48 default : state_name = "S0";49 endcase50 //-----------------51 52 //----fsm_inst----53 fsmfsm_inst(54 .clk (clk),//inputclk55 .rst_n(rst_n),//inputrst_n56 .din(din),//inputdin57 58 .dout(dout)//outputdout59 );60 61 endmodule//---------------用QuestaSim仿真出的波形如下所示:
15、【简答题】有一套四位数加密系统,输入四位数以后会自动加密,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,分别再将第一位和第四位交换,第二位和第三位交换,请用C语言写出加密算法(15分)解析:本题目主要考察了C语言编程技能这道题目是通过C语言实现一个小算法,其实并不难,所考察到的C语言知识点也比较有限,相关专业的同学肯定都学习过C语言,且Verilog语言也是基于C进行的改进,所以对大家来说并不难。IC岗之所以考察C语言相关的内容我认为主要基于以下几点的考虑:1)协助验证工程师做系统级验证。在做验证时不仅仅会用到SystemVerilog和UVM,有时还会直接对软CPU的寄存器进行配置,以此来做带CPU的系统验证,即模拟嵌入式开发的过程。先编写C语言配置寄存器的代码,然后通过编译器把C语言编译成CPU可以直接读取的hex等文件放入到ROM中,在CPU初始化的时候读取ROM中的内容,从而实现对系统做一些配置工作。2)协助芯片测试工程师测试。在做芯片测试时,有些时候会需要设计工程师配合,因为设计工程师对寄存器的配置是最清楚的。而芯片测试时往往会涉及到嵌入式、单片机等相关的寄存器配置,都会用到嵌入式C语言。3)编写一些简单的处理脚本。其实C语言也可以实现一些相关的操作,虽然没有上一节我们讲过的脚本使用起来那么方便,但做一些简单的数据处理还是游刃有余的。本题的C语言参考代码如下所示://----------01 #include <stdio.h>02 03 int main()04 {05 int din;06 char A, B, C, D;07 char A1, B1, C1, D1;08 int dout;09 10 while(1){11 printf("please input din: "); 12 scanf("%d", &din); //输入一个4位数13 14 //输入大于4位数以外的值直接退出15 if(din < 10000){16 //C语言中最常用的取位方法17 A = din/1000; //取千位18 B = (din%1000)/100;//取百位19 C = (din%100)/10; //取十位20 D = (din%10); //取个位21 22 //每一位都加5求余数后替换该位23 A1 = (A+5)%10; 24 B1 = (B+5)%10;25 C1 = (C+5)%10;26 D1 = (D+5)%10;27 28 //第1位和第4位交换 29 dout = D1*1000+C1*100+B1*10+A1;30 printf("dout = %d ", dout); 31 }32 else{33 printf("Exit ");34 break; 35 }36 }37 return 0; 38 }
//--------------
使用CodeBlocks编译得到的结果如下所示:
审核编辑:汤梓红