Shift4

异步复位同步置数和使能。

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 or posedge areset)
    begin
        if(areset)
            q <= 'd0;
        else if(load)
            q <= data;
        else if(ena)
            q <= {1'b0,q[3:1]};
    end
endmodule

Rotate100

循环移位,通过ena信号控制左移和右移。

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 if(ena == 2'b01)
            q <= {q[0],q[99:1]};
        else if(ena == 2'b10)
            q <= {q[98:0],q[99]};
    end
endmodule

Shift18

算数移位,注意右移的时候保留符号位,左移正常移位就可以,注意8{q[63]}外面要再加一个大括号。

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)
    begin
        if(load)
            q <= data;
        else if(ena) begin
            case(amount)
                2'b00: q <= {q[62:0],1'b0};
                2'b01: q <= {q[55:0],8'b0};
                2'b10: q <= {q[63],q[63:1]};
                2'b11: q <= {{8{q[63]}},q[63:8]};
            endcase
        end
    end
endmodule

Lfsr5

题目给的答案把组合逻辑和时序逻辑分开了,看起来思路会更清晰。

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output reg[4:0] q
); 
    always@(posedge clk)
    begin
        if(reset)
            q <= 5'h1;
        else begin
            q[0] <= q[1];
            q[1] <= q[2];
            q[2] <= q[3]^q[0];
            q[3] <= q[4];
            q[4] <= 1'b0^q[0];
        end
    end
endmodule

Mt2015 lfsr

把之前写的muxdff例化一下就可以了,注意如果是在顶层是不推荐有逻辑的,逻辑可以纳入子模块中,可以更好的优化。

module top_module (
    input [2:0] SW,      // R
    input [1:0] KEY,     // L and clk
    output [2:0] LEDR);  // Q
    muxdff u0(KEY[0],KEY[1],SW[0],LEDR[2],LEDR[0]);
    muxdff u1(KEY[0],KEY[1],SW[1],LEDR[0],LEDR[1]);
    muxdff u2(KEY[0],KEY[1],SW[2],LEDR[1]^LEDR[2],LEDR[2]);
endmodule
module muxdff (
    input clk,
    input L,
    input r_in,
    input q_in,
    output reg Q);
    always@(posedge clk)
    begin
        Q <= L?r_in:q_in;
    end
endmodule

Lfsr32

仿照Lfsr5写即可,注意位置是从1开始算的。

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output reg[31:0] q
); 
    reg [31:0]q_next;
    always@(*)
    begin
        q_next = q[31:1];
        q_next[31] = q[0];
        q_next[21] = q[0]^q[22];
        q_next[1] = q[0]^q[2];
        q_next[0] = q[0]^q[1];
    end
    always@(posedge clk)
    begin
        if(reset)
            q <= 32'h1;
        else
            q <= q_next;
    end
endmodule

Exams/m2014 q4k

module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);
    reg [3:0]Q;
    always@(posedge clk)
    begin
        if(~resetn)
            Q <= 'd0;
        else 
            Q <= {in,Q[3:1]};
    end
    assign out = Q[0];
endmodule

Exams/2014 q4b

同样是例化之前写的MUXDFF。

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
    MUXDFF u3(KEY[0],LEDR[1],SW[0],KEY[1],KEY[2],LEDR[0]);
    MUXDFF u2(KEY[0],LEDR[2],SW[1],KEY[1],KEY[2],LEDR[1]);
    MUXDFF u1(KEY[0],LEDR[3],SW[2],KEY[1],KEY[2],LEDR[2]);
    MUXDFF u0(KEY[0],KEY[3],SW[3],KEY[1],KEY[2],LEDR[3]);
endmodule
module MUXDFF (
    input clk,
    input w, R, E, L,
    output Q
);
    always@(posedge clk)
    begin
        Q <= L?R:(E?w:Q);
    end
endmodule

Exams/ece241 2013 q12

3输入查找表,Xilinx的FPGA大多是基于6输入查找表构造的。

通过一个时序逻辑改变保存的值,再通过一个组合逻辑输出结果。

module top_module (
    input clk,
    input enable,
    input S,
    input A, B, C,
    output Z ); 
    reg [7:0]Q;
    always@(posedge clk)
    begin
        if(enable)
            Q <= {Q[6:0],S};
    end
    assign Z=Q[{A,B,C}];
endmodule