今天继续为大家解析联发科技数字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编译得到的结果如下所示:审核编辑:汤梓红
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)