Shift Registers
4-bit shift register
重點是寫個shift register,唯一要注意的是load優先級比enable大。
Verilog
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)begin
if(areset) q <= 4'b0000;
else if(load) q <= data;
else if(ena) q <= q >> 1;
else q <= q;
end
endmodule
Left/right rotator
重點是寫個rotator,可以使用concatenation來實現rotate。
Verilog
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'b00: q <= q;
2'b01: q <= { q[0], q[99:1]};
2'b10: q <= { q[98:0], q[99]};
2'b11: q <= q;
endcase
end
end
endmodule
Left/right arithmetic shift by 1 or 8
實作arithmetic shift,需注意的是arithmetic shift往右位移時,高位要用補數補位。
Verilog
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'b0000_0000};
2'b10: q <= {q[63],q[63:1]};
2'b11: q <= {{8{q[63]}},q[63:8]};
endcase
end
else q <= q;
end
endmodule
5-bit LFSR
原題:5-bit LFSR
實作LFSR。
Verilog
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'b00001;
else q <= {q[0],q[4],q[3] ^ q[0],q[2:1]};
end
endmodule
3-bit LFSR
原題:3-bit LFSR
和前一題一樣實作LFSR。
Verilog
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
always@(posedge KEY[0])begin
LEDR <= KEY[1] ? SW: {LEDR[1]^LEDR[2],LEDR[0],LEDR[2]};
end
endmodule
32-bit LFSR
原題:32-bit LFSR
還是實作LFSR,taps的意思是指在對應的output放上xor q[0],例如taps at 1意思就是q[1] ^ q[0]。
Verilog
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output reg [31:0] q
);
always@(posedge clk)begin
if(reset) q <= 32'h1;
else q <= {q[0],q[31:23],q[22]^q[0],q[21:3],q[2]^q[0],q[1]^q[0]};
end
endmodule
Shift register(1)
練習pipeline怎麼切,總之就是多開幾個reg。
Verilog
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output reg out);
reg q1, q2, q3;
always@(posedge clk)begin
if(~resetn) {q1,q2,q3,out} <= 4'b0000;
else {q1,q2,q3,out} <= {in,q1,q2,q3};
end
endmodule
Shift register(2)
練習寫一個module,然後接成pipeline。
Verilog
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
); //
MUXDFF ff0( .E(KEY[1]), .clk(KEY[0]), .L(KEY[2]), .w(LEDR[1]), .R(SW[0]), .q(LEDR[0]));
MUXDFF ff1( .E(KEY[1]), .clk(KEY[0]), .L(KEY[2]), .w(LEDR[2]), .R(SW[1]), .q(LEDR[1]));
MUXDFF ff2( .E(KEY[1]), .clk(KEY[0]), .L(KEY[2]), .w(LEDR[3]), .R(SW[2]), .q(LEDR[2]));
MUXDFF ff3( .E(KEY[1]), .clk(KEY[0]), .L(KEY[2]), .w(KEY[3]), .R(SW[3]), .q(LEDR[3]));
endmodule
module MUXDFF (
input E,
input clk,
input L,
input w,
input R,
output q);
always@(posedge clk)begin
case({L,E})
2'b00: q <= q;
2'b01: q <= w;
default: q <= R;
endcase
end
endmodule
3-input LUT
原題:3-input LUT
練習寫一個shift register和multiplexer。