Reference to GPT and their own ideas, the following is a pseudo random sequence generator based on Verilog HDL language, using the generation of polynomial 1+x^3+x^7. The generator has a RESET terminal and two control terminals to set the initial value of the register and display the generated pseudo-random sequence on the digital tube.
module PRBS(
input clk, // 时钟信号
input rst, // 复位信号
input ctrl1, // 控制信号1
input ctrl2, // 控制信号2
output reg [7:0] led // 数码管输出
);
reg [7:0] shift_reg; // 移位寄存器
reg [2:0] control; // 控制信号
always @(posedge clk, negedge rst) begin
if(~rst) begin // 复位信号
shift_reg <= 8'h0;
control <= 3'b0;
end else begin
if(ctrl1) begin // 设置寄存器初值
case(control)
3'b000: shift_reg <= 8'h01;
3'b001: shift_reg <= 8'h7E;
3'b010: shift_reg <= 8'hAA;
3'b011: shift_reg <= 8'h55;
default: shift_reg <= 8'h0;
endcase
control <= control + 1;
end else if(ctrl2) begin // 反转寄存器初值
shift_reg <= ~shift_reg;
end else begin
// 移位操作,生成伪随机序列
shift_reg <= {shift_reg[6:0], shift_reg[7] ^ shift_reg[3] ^ shift_reg[0]};
end
end
end
// 数码管驱动模块,实现BCD码转换并在数码管上显示
display_7seg displayer(shift_reg, led);
endmodule
// 数码管驱动模块
module display_7seg(
input [7:0] num, // 要显示的数字
output reg [7:0] seg // 数码管输出
);
reg [3:0] bcd; // BCD码
// BCD码转换
always @* begin
case(num)
8'h00: bcd = 4'b0000;
8'h01: bcd = 4'b0001;
8'h02: bcd = 4'b0010;
8'h03: bcd = 4'b0011;
8'h04: bcd = 4'b0100;
8'h05: bcd = 4'b0101;
8'h06: bcd = 4'b0110;
8'h07: bcd = 4'b0111;
8'h08: bcd = 4'b1000;
8'h09: bcd = 4'b1001;
8'h0A: bcd = 4'b1010;
8'h0B: bcd = 4'b1011;
8'h0C: bcd = 4'b1100;
8'h0D: bcd = 4'b1101;
8'h0E: bcd = 4'b1110;
8'h0F: bcd = 4'b1111;
default: bcd = 4'bXXXX; // 非法BCD码
endcase
end
// 显示BCD码
always @* begin
case(bcd)
4'b0000: display = 7'b1000000; // 显示0
4'b0001: display = 7'b1111001; // 显示1
4'b0010: display = 7'b0100100; // 显示2
4'b0011: display = 7'b0110000; // 显示3
4'b0100: display = 7'b0011001; // 显示4
4'b0101: display = 7'b0010010; // 显示5
4'b0110: display = 7'b0000010; // 显示6
4'b0111: display = 7'b1111000; // 显示7
4'b1000: display = 7'b0000000; // 显示8
4'b1001: display = 7'b0010000; // 显示9
4'b1010: display = 7'b0001000; // 显示A
4'b1011: display = 7'b0000011; // 显示B
4'b1100: display = 7'b1000110; // 显示C
4'b1101: display = 7'b0100001; // 显示D
4'b1110: display = 7'b0000110; // 显示E
4'b1111: display = 7'b0001110; // 显示F
default: display = 7'b1111111; // 不显示
endcase
end
// 伪随机序列发生器
reg [7:0] shift_reg = 8'h7F; // 初始值为7FH
always @(posedge clk or negedge reset) begin
if (!reset) begin
shift_reg <= 8'h7F;
end else begin
shift_reg <= {shift_reg[6]^shift_reg[0], shift_reg[7:1]};
end
end
// 选择控制信号
wire [1:0] ctrl = {sw[2], sw[1]};
// 设置初值
always @* begin
case(ctrl)
2'b00: shift_reg = 8'h7F; // 初始值为7FH
2'b01: shift_reg = 8'h3D; // 初始值为3DH
2'b10: shift_reg = 8'h5E; // 初始值为5EH
2'b11: shift_reg = 8'h6A; // 初始值为6AH
default: shift_reg = 8'h7F; // 默认初始值为7FH
endcase
end
// 数码管显示控制
reg [3:0] cnt = 4'b0000; // 显示计数器
reg [3:0] index = 4'b0000; // 数码管位选计数器
wire [6:0] segment = display; // 数码管段选信号
reg [3:0] buffer [0:3]; // 数码管缓存
// 数码管扫描
always @(posedge clk) begin
if (reset) begin // 复位
cnt <= 4'b0000;
index <= 4'b0000;
buffer <= 4'b0000;
end
else begin
cnt <= cnt + 1; // 显示计数器自增
if (cnt == 4'b1000) begin
cnt <= 4'b0000;
index <= index + 1; // 数码管位选计数器自增
if (index == 4'b0100) // 最后一位后回到第一位
index <= 4'b0000;
end
end
end
// 数码管数据缓存
always @(posedge clk) begin
if (reset) // 复位
buffer <= 4'b0000;
else begin
case (index) // 根据当前位选计数器的值更新相应的缓存值
4'b0000: buffer[0] <= num;
4'b0001: buffer[1] <= num;
4'b0010: buffer[2] <= num;
4'b0011: buffer[3] <= num;
endcase
end
end
// 数码管段选控制
assign display = segment[index] ? buffer[index] : 7'b111_1111; // 根据位选控制信号选择显示的数值或不显示
// 数码管共阴极控制
assign cathode = 4'b1110 - index; // 根据位选控制信号计算激活的共阴极,因为我们使用的是共阴极的数码管
always @(posedge clk) begin
if (rst) begin
cnt <= 4'b0000;
index <= 4'b0000;
buffer <= 4'b0000;
end
else begin
if (cnt == 4'b1000) begin // 8个时钟周期后更新显示
cnt <= 4'b0000;
index <= index + 1;
if (index == 4'b1000) // 四个数码管显示完毕后回到第一个
index <= 4'b0000;
end
else begin
cnt <= cnt + 1;
buffer[index] <= bcd_data;
end
end
end
assign display = { // 根据当前位选和缓存中的数据计算数码管段选信号
buffer[3][seg],
buffer[2][seg],
buffer[1][seg],
buffer[0][seg]
};