HDLBits刷题(Shift Register&Finite State Machines))

第一题:Build a 4-bit shift register (right shift), with asynchronous reset, synchronous load, and enable.

  • areset: Resets shift register to zero.
  • load: Loads shift register with data[3:0] instead of shifting.
  • ena: Shift right (q[3] becomes zero, q[0] is shifted out and disappears).
  • q: The contents of the shift register.
    If both the load and ena inputs are asserted (1), the load input has higher priority.
module top_module(
    input clk,
    input areset,  // async active-high reset to zero
    input load,
    input ena,
    input [3:0] data,
    output reg [3:0] q);
    
    always@(posedge clk,posedge areset)
        if(areset)
            q <= 0;
        else if(load) 
            q <= data;
        else if(ena)
            q <= {1'd0,q[3:1]};   
            
endmodule
------------------------/*官网参考答案*/-----------------------------
module top_module(
    input clk,
    input areset,
    input load,
    input ena,
    input [3:0] data,
    output reg [3:0] q);
    
    // Asynchronous reset: Notice the sensitivity list.
    // The shift register has four modes:
    //   reset
    //   load
    //   enable shift
    //   idle -- preserve q (i.e., DFFs)
    always @(posedge clk, posedge areset) begin
        if (areset)     // reset
            q <= 0;
        else if (load)  // load
            q <= data;
        else if (ena)   // shift is enabled
            q <= q[3:1];    // Use vector part select to express a shift.
    end
    
endmodule

第二题:Build a 100-bit left/right rotator, with synchronous load and left/right enable. A rotator shifts-in the shifted-out bit from the other end of the register, unlike a shifter that discards the shifted-out bit and shifts in a zero. If enabled, a rotator rotates the bits around and does not modify/discard them.

  • load: Loads shift register with data[99:0] instead of rotating.
  • ena[1:0]: Chooses whether and which direction to rotate.
    2'b01 rotates right by one bit
    2'b10 rotates left by one bit
    2'b00 and 2'b11 do not rotate.
  • q: The contents of the rotator.
module top_module(
    input clk,
    input load,
    input [1:0] ena,
    input [99:0] data,
    output reg [99:0] q); 
    
   always@(posedge clk) begin
       if(load) q<= data;
        else begin
            case(ena)
                2'b01: q<={q[0],q[99:1]};
                2'b10: q<={q[98:0],q[99]};
                2'b00: q<=q;
                2'b11:q<=q;
            endcase
        end
   end

endmodule
-   --------------------------官网参考答案 --------------------
module top_module(
    input clk,
    input load,
    input [1:0] ena,
    input [99:0] data,
    output reg [99:0] q);
    
    // This rotator has 4 modes:
    //   load
    //   rotate left
    //   rotate right
    //   do nothing
    // I used vector part-select and concatenation to express a rotation.
    // Edge-sensitive always block: Use non-blocking assignments.
    always @(posedge clk) begin
        if (load)       // Load
            q <= data;
        else if (ena == 2'h1)   // Rotate right
            q <= {q[0], q[99:1]};
        else if (ena == 2'h2)   // Rotate left
            q <= {q[98:0], q[99]};
    end
endmodule

第三题:Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by amount.
An arithmetic right shift shifts in the sign bit of the number in the shift register (q[63] in this case) instead of zero as done by a logical right shift. Another way of thinking about an arithmetic right shift is that it assumes the number being shifted is signed and preserves the sign, so that arithmetic right shift divides a signed number by a power of two.
There is no difference between logical and arithmetic left shifts.

module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [63:0] data,
    output reg [63:0] q); 
    
    always@(posedge clk) 
        if(load)
            q <= data;
        else if(ena)
            case(amount)
                2'b00 : q <= {q[62:0],1'd0};
                2'b01 : q <= {q[55:0],8'd0};
                2'b10 : q <= {q[63],q[63:1]};
                2'b11 : q <= {{8{q[63]}},q[63:8]};
            endcase
            
endmodule

第四题:有序状态机的一道入门题。感觉自己对有限状态机的理解还是不够好!


image.png

题目给定的是莫尔型状态机,在这里,首先需要清楚一个概念 :即根据输出信号的产生:有限状态机分为两种:

  • Mealy(米利型):Mealy型状态机的输出与当前状态和输入有关系;
  • Moore(莫尔型) :Moore型状态机仅与当前状态有关,而与输出无关。
    对于状态机的写法,常用的有两段式和三段式;
    不过一般建议用三段式编写,比较方便易,读
module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output out);//  

    parameter A=0, B=1; 
    reg state, next_state;

    always @(*) begin    // This is a combinational always block
        case(state)
            A: if(in)
                    next_state <= A;
                else
                    next_state <= B;// State transition logic
            B: if(in)
                next_state <= B;
                else
                next_state <= A;
        endcase
    end

    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        if(areset)
            state <= B;
        else
            state <= next_state;// State flip-flops with asynchronous reset
    end
            
    assign  out = state == B ? 1: 0;
    // Output logic
    // assign out = (state == ...);

endmodule
------------------------------------官网参考答案---------------------------------
module top_module (
    input clk,
    input in,
    input areset,
    output out
);

    // Give state names and assignments. I'm lazy, so I like to use decimal numbers.
    // It doesn't really matter what assignment is used, as long as they're unique.
    parameter A=0, B=1;
    reg state;      // Ensure state and next are big enough to hold the state encoding.
    reg next;
    
    
    // A finite state machine is usually coded in three parts:
    //   State transition logic   状态转移方程
    //   State flip-flops       激励方程
    //   Output logic          输出方程
    // It is sometimes possible to combine one or more of these blobs of code
    // together, but be careful: Some blobs are combinational circuits, while some
    // are clocked (DFFs).
    
    
    // Combinational always block for state transition logic. Given the current state and inputs,
    // what should be next state be?
    // Combinational always block: Use blocking assignments.
    always@(*) begin
        case (state)
            A: next = in ? A : B;
            B: next = in ? B : A;
        endcase
    end
    
    
    
    // Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset.
    always @(posedge clk, posedge areset) begin
        if (areset) state <= B;     // Reset to state B
        else state <= next;         // Otherwise, cause the state to transition
    end
        
        
        
    // Combinational output logic. In this problem, an assign statement is the simplest.
    // In more complex circuits, a combinational always block may be more suitable.
    assign out = (state==B);

    
endmodule

image.png
/*这里不能使用非阻塞赋值语句的原因没有搞懂*/
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out;//  
    reg out;

    parameter A=0,B=1; // Fill in state name declarations

    reg present_state, next_state;

    always @(posedge clk) begin
        if (reset) begin  
            // Fill in reset logic
            out <= B;
            present_state <= B;
        end else begin
            case (present_state) 
                // Fill in state transition logic
                A:
                    if(in) next_state = A;
                    else next_state = B;
                B:
                    if(in) next_state = B;
                    else next_state = A;
               
            endcase
            

            // State flip-flops
            present_state = next_state;   

                case (present_state)
                // Fill in output logic
                A:out = A;
                B:out = B;
              
            endcase
        end
    end

endmodule

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容