错题集:HDLBits Fsm serialdata

错题记录:

这是一道有关串行协议的题,在发送数据时,首先发送的是低位。

这道题我用了两种方法,第二种方法花了接近一天的时间才找到问题所在,主要是由于忽略了阻塞赋值和非阻塞赋值,这两者的差别造成的。

(1)阻塞赋值和非阻塞赋值 

我一开始temp 《= {in,out_byte}; out_byte 《= temp[8:1]; 使用的是非阻塞赋值,这样是错误的,应该使用阻塞赋值。因为只有在阻塞赋值下,才是先进行temp = {in,out_byte};这一句的赋值,得到了新的temp以后,再顺利的完成预期中的out_byte= temp[8:1];的赋值。

(2)对沿触发型always块的理解误区

我之前一直认为,边沿触发的always块,代表的一定是时序逻辑,所以在always块内部只能使用“非阻塞赋值”(《= ),但是实际上,是可以使用 “阻塞赋值” (=)的。

  • 阻塞赋值 表示 组合逻辑,非阻塞赋值 表示 时序逻辑。
  • 沿触发的always块常常用于描述时序行为,但是在其内部,也是可以出现组合逻辑的。

题目:

现在,您已经有了一个有限的状态机,可以识别何时在串行比特流中正确接收字节,请添加一个数据路径,该路径将输出正确接收的数据字节。out_byte在完成时需要有效,否则就是不在乎。

请注意,串行协议首先发送最低有效位。

 正确答案:(重点在于先发送最低有效位)

方法一:temp = {in,out_byte};//不断接收in,拼接在temp的前面。
              out_byte = temp[8:1];//不断的取temp的高8位。

注意:不能写成out_byte = {in,out_byte}。因为这样会位宽不够,而导致只截取到了低八位的数据

方法二:out_byte <= {out_byte,in};//不断接收in,拼接在末位;

              out_byte <={out_byte[0],out_byte[1],out_byte[2],out_byte[3],out_byte[4],

out_byte[5],out_byte[6],out_byte[7]}; //然后再交换各位的位置

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    reg [8:0] temp;
    reg [3:0] state,next_state;
    parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5,S6=6,S7=7,S8=8,S9=9,DONE=10,ERROR=11;
    
    always@(*)begin
        case(state)
            S0: next_state = in?S0:S1;
            S1: next_state = S2;
            S2: next_state = S3;
            S3: next_state = S4;
            S4: next_state = S5;
            S5: next_state = S6;
            S6: next_state = S7;
            S7: next_state = S8;
            S8: next_state = S9;
            S9: next_state = in?DONE:ERROR;
          DONE: next_state = in?S0:S1;
         ERROR: next_state = in?S0:ERROR;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)
            state <= S0;
        else
            state <= next_state;
    end
    
    assign done = (state==DONE);
    // Use FSM from Fsm_serial

    always@(posedge clk)begin// New: Datapath to latch input bits. //方法一
        if(reset)begin
            out_byte <= 8'b0;//时序逻辑
            temp <= 9'b0;
        end
        else if((S1<=state)&&(state<=S8))begin
            temp = {in,out_byte};//这里应该是组合逻辑,原来错写为了temp 《= {in,out_byte};
            temp = {in,out_byte};//这里应该是组合逻辑,原来错写为了temp 《= {in,out_byte};
        end
        else if(state==S9)
            out_byte <= out_byte;//时序逻辑
    end 
    
//    always@(posedge clk)begin// New: Datapath to latch input bits. //方法二
//        if(reset)
//            out_byte <= 8'b0;
//        else if((S1<=state)&&(state<=S8))
//       		out_byte <= {out_byte,in};
//        else if(state==S9)
//            out_byte <= {out_byte[0],out_byte[1],out_byte[2],out_byte[3],out_byte[4],out_byte[5],out_byte[6],out_byte[7]};
//    end

endmodule

成功的仿真:

 报错的仿真:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值