龙空技术网

求职攻略| 如何用Verilog实现串转并电路

嵌入式范范 141

前言:

而今同学们对“串并转换的原理分析”可能比较着重,大家都想要剖析一些“串并转换的原理分析”的相关内容。那么小编也在网络上收集了一些对于“串并转换的原理分析””的相关文章,希望同学们能喜欢,朋友们快快来了解一下吧!

有奖调查:达尔闻即将要推出一套TI的权威电源培训系列课程,线上培训+线下EVM实操。在此之前,我们设定了一些问题,希望了解大家的需求,我们会送出一些精美礼品。

→点击这里填写问卷

今天继续为大家解析艾为电子数字IC设计岗剩下的笔试题。

4、程序改错题(10分)

//-----------------------------

01 moduletest(

02 inputclk,

03 input[7:0]addr,

04 inputreq,

05 inputrst_n,

06 inputwen,

07 input[15:0]wdata,

08 output[15:0]datao,

09 )

10

11 reg [15:0]mem [7:0];

12

13 always@(posedge clk or negedge rst_n) begin

14 if(rst_n) begin

15 mem = 0;

16 end else if(wen) begin

17 mem[addr] = wdata;

18 end

19

20 always@(req)

21 if(req)

22 datao <= mem[addr];

23

24 endmodule

//----------------------------

解析:本题主要考察了对Verilog语法规范的敏感性。这种题目在没有编译器的情况下,纯靠观察来找语法问题,需要对Verilog代码有一定的敏感度才能够找全。如果是一个新手或者写代码不多的人想在短时间内全部把错误都找出来还是有些困难的。根据分值设置和代码量可以初步预判大概有不少于5个的错误。错误如下所示:

1)第08行的结尾,不能有“,”

2)第09行的结尾,应该有“;”

3)第16行的“begin”没有与之匹配的“end”

4)第15行二维数组在赋初值时不能直接分配给数组整体初值,只能分配给单个元素初值,也可以使用initial读取初始化文件中的初始化值

5)datao信号在always块中被赋值,所以第08行应该把datao信号定义为reg型变量,缺省情况下默认为wire型变量

另外还有两处不严谨的地方,这种不严谨的问题虽然在本次设计中不会出现问题,但是并不推荐这种写法,具有潜在的危险:

1)第一个表达时序逻辑的always块应该推荐使用“<=”赋值方式,第二个表达组合逻辑的always块应该推荐使用“=”赋值方式

2)第20行always块中的敏感列表不全,推荐使用通配符“*”

还有一处需要注意的地方:在表达组合逻辑的第二个always块中的“if”没有对应的“else”,这虽然不能算是错误,但产生latch时一定要是设计者已知的。

修改完毕后的代码如下所示:

//------------------------------

01 moduletest(

02 inputclk,

03 input[7:0]addr,

04 inputreq,

05 inputrst_n,

06 inputwen,

07 input[15:0]wdata,

08 outputreg[15:0]datao

09 );

10

11 reg [15:0]mem [7:0];

12

13 always@(posedge clk or negedge rst_n) begin

14 if(rst_n) begin

15 mem[addr] <= 15'd0;

16 end else if(wen) begin

17 mem[addr] <= wdata;

18 end

19 end

20

21 always@(*)

22 if(req)

23 datao = mem[addr];

24 else

25 datao = 15'd0;

26

27 endmodule

//---------------------------------

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。

点击这里找小助理0元领取:加微信领取资料

5、用Verilog实现串转并电路,输出信号8bit,同时可选择模式LSB或者MSB优先。(10分)

解析:本题主要考察了可切换的串并转换的Verilog实现

串并转换在Verilog中经常会用到,由于芯片外部的PAD数量有限,所以多用串行的方式把数据送入,然后在芯片内部再转成并行数据进行处理。我们可以选择用寄存器移位的方式实现,也可以选择用FIFO或RAM来实现,这题显然是要求我们用寄存器移位的方式来实现。题目中还要求LSB和MSB可切换的功能,这里我们通过一个输入信号来控制,这个信号在芯片中往往都是做成寄存器可配,由专门的reg bank模块来控制。Verilog代码如下所示:

//------------------------------

01 moduleserial2parrallel(

02 inputsys_clk,//模块的时钟

03 inputsys_rst_n,//模块的复位

04 inputreg_msb_lsb,//为1时表示先传来的MSB数据,为0时表示先传来的LSB数据

05 inputdata_in,//单比特串行数据

06 inputdata_in_valid, //单比特串行数据有效标志信号

07

08 outputreg[7:0]data_out,//8比特串并数据

09 outputregdata_out_valid//8比特串行数据有效标志信号

10 );

11

12 reg [2:0] cnt;

13

14 //当单比特串行数据有效标志信号有效时计数器计数

15 always@(posedge sys_clk or negedge sys_rst_n)

16 if(!sys_rst_n)

17 cnt <= 3'b0;

18 elseif(data_in_valid == 1'b0 && cnt == 3'd7)

19 cnt <= 3'b0;

20 elseif(data_in_valid == 1'b1)

21 cnt <= cnt + 1'b1;

22

23 //当单比特串行数据有效标志信号有效且先传来MSB数据执行左移;当单比特串行数据有效标志信号有效且先传来LSB数据执行右移

24 always@(posedge sys_clk or negedge sys_rst_n)

25 if(!sys_rst_n)

26 data_out <= 8'b0;

27 elseif(data_in_valid == 1'b1 && reg_msb_lsb == 1'b1)

28 data_out <= {data_out[6:0], data_in};

29 elseif(data_in_valid == 1'b1 && reg_msb_lsb == 1'b0)

30 data_out <= {data_in, data_out[7:1]};

31

32 //当移动8次后,8比特并行数据有效

33 always@(posedge sys_clk or negedge sys_rst_n)

34 if(!sys_rst_n)

35 data_out_valid <= 8'b0;

36 elseif(cnt == 3'd7)

37 data_out_valid <= 1'b1;

38 else

39 data_out_valid <= 1'b0;

40

41 endmodule

//---------------------------------

Testbench如下所示:

//---------------------------------

01 `timescale1ns/1ns

02

03 moduletb_serial2parrallel();

04

05 regsys_clk;

06 regsys_rst_n;

07 regreg_msb_lsb;

08 regdata_in;

09 regdata_in_valid;

10

11 wire[7:0]data_out;

12 wiredata_out_valid;

13

14 //初始化系统时钟、全局复位和输入信号

15 initialbegin

16 sys_clk = 1'b1;

17 sys_rst_n <= 1'b0;

18 reg_msb_lsb <= 1'b1;

19 data_in <= 1'b0;

20 data_in_valid <= 1'b0;

21 #20;

22 sys_rst_n <= 1'b1;

23 end

24

25 //调用任务data_in_byte

26 initialbegin

27 #200

28 data_in_byte();

29 end

30

31 //sys_clk:每10ns电平翻转一次,产生一个50MHz的时钟信号

32 always #10 sys_clk = ~sys_clk;

33

34 //创建任务rx_byte,本次任务调用data_in_bit任务,发送8次数据,分别为0~7

35 taskdata_in_byte();//因为不需要外部传递参数,所以括号中没有输入

36 integerj;

37 for(j=0; j<8; j=j+1)begin//调用8次data_in_bit任务,每次发送的值从0变化7

38 data_in_valid <= 1'b1;

39 data_in_bit(j);

40 data_in_valid <= 1'b0;

41 end

42 endtask

43

44 //创建任务data_in_bit,每次发送的数据有8位,data的值分别为0到7由j的值传递进来

45 taskdata_in_bit(

46 input[7:0]data

47 );

48 integeri;

49 for(i=0; i<8; i=i+1)begin

50 case(i)

51 0: data_in <= data[0];

52 1: data_in <= data[1];

53 2: data_in <= data[2];

54 3: data_in <= data[3];

55 4: data_in <= data[4];

56 5: data_in <= data[5];

57 6: data_in <= data[6];

58 7: data_in <= data[7];

59 endcase

60 #(20); //没间隔20ns发送1比特数据

61 end

62 endtask

63

64//--------serial2parrallel_inst------

65 serial2parrallelserial2parrallel_inst(

66 .sys_clk(sys_clk),//inputsys_clk

67 .sys_rst_n(sys_rst_n), //inputsys_rst_n

68 .reg_msb_lsb(reg_msb_lsb), //inputreg_msb_lsb

69 .data_in(data_in),//inputdata_in

70 .data_in_valid(data_in_valid),//inputdata_in_valid

71

72 .data_out (data_out), //output[7:0]data_out

73 .data_out_valid(data_out_valid)//outputdata_out_valid

74 );

75

76 endmodule

//-------------------------------

仿真结果这里不再给出,大家可以自行验证一下。

6、艾师傅卖羊肉,进价24一公斤,卖18一斤,客人买了四公斤,客人给两百元但找不开,艾师傅到邻居家换了两百元钱,后来邻居去银行存钱发现这两百元是假币,艾师傅又赔了邻居200,请问艾师傅一共赔了多少钱?(10分)

解析:本题主要考察了如何从复杂的逻辑中理清关键逻辑

这是一道逻辑推理计算题,题目中给了很多和要求计算结果无关的信息作为干扰,如果不能够快速判断并排除这些无关信息,则会陷入题目的陷阱里。问题是“艾师傅一共赔了多少钱?”,所以后半部分艾师傅到邻居家换钱又换回来这个线索完全是没有用的,因为艾师傅从邻居那里换到的200元真币又赔给了邻居,所以艾师傅没有赚也没有赔。而前面卖肉的过程所亏的钱需要关注的点就是给客人肉的本钱和找零的钱。

卖4公斤肉亏的钱就是进肉价格所亏的本钱为:24¥/kg*4kg=96¥;200元假币找零所亏的钱为:200¥-36¥/kg*4kg=56¥,所以艾师傅总的亏损为:96¥+56¥=152¥。

文章链接:

转载自:达尔闻说,作者相量子

文章链接:求职攻略| 如何用Verilog实现串转并电路

标签: #串并转换的原理分析