0
Follow
0
View

Design of Pseudo-Random Sequence Generator(HDL Language)

cupidcool 注册会员
2023-02-28 12:30

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]
};
dongfeng19811020 注册会员
2023-02-28 12:30

This answer references ChatGPT
Here is the full Verilog code:


module prbs_generator (
    input wire clk,
    input wire reset,
    input wire [1:0] control,
    output reg [3:0] display
);

reg [7:0] state;

always @(posedge clk) begin
    if (reset) begin
        // 清零寄存器
        state <= 8'h00;
    end else begin
        // 选择初始值
        case (control)
            2'b00: state <= 8'h5F;
            2'b01: state <= 8'h3C;
            2'b10: state <= 8'h9A;
            2'b11: state <= 8'h1E;
        endcase

        // 生成新状态
        state <= {state[6]^state[3], state[7:1]};
    end
end

always @(*) begin
    case (state)
        8'h00: display = 4'b0111;
        8'h01: display = 4'b0001;
        8'h02: display = 4'b1011;
        8'h03: display = 4'b1000;
        8'h04: display = 4'b1100;
        8'h05: display = 4'b1001;
        8'h06: display = 4'b1111;
        8'h07: display = 4'b0000;
        8'h08: display = 4'b1110;
        8'h09: display = 4'b1001;
        8'h0A: display = 4'b1111;
        8'h0B: display = 4'b1101;
        8'h0C: display = 4'b0110;
        8'h0D: display = 4'b1111;
        8'h0E: display = 4'b1101;
        8'h0F: display = 4'b0111;
        default: display = 4'b1111;
    endcase
end

endmodule

In the above code, we first define a module named prbs_generator, which has a clock end clk, a zeroclearing end reset, two controllers control, and a four digit tube output display. Next, we define an 8-bit register, state, which holds the current state. When the clock rises, if reset is 1, we clear the register to zero. Otherwise, we choose a different initial value based on the value of the control and generate a new state based on the polynomial 1+x^3+x^7. Finally, we map the state to the nixie tube and output the result to the display port.

Notice that we use @( ) in the final always block to indicate that this is a combinatorial logical block. This means that when the value of state changes, the value of display will be updated immediately. Since this block does not have a clock edge trigger, we use @( ) to prevent infinite loop behavior.

doublewood21 注册会员
2023-02-28 12:30

Monster group and GPT based adjustable write: < br / > the following is a basic design using HDL language pseudo-random sequence generator, using the generating polynomial for | + x ~ 3 + x ^ 7. It includes a RESET terminal and two control terminals for adjusting the initial value of the register, and can display the generated pseudo-random sequence on the nixtube.

module pseudo_random_seq(
  input clk,
  input rst,
  input ctrl1,
  input ctrl2,
  output reg [7:0] display
);

reg [6:0] shift_reg;

always @(posedge clk or posedge rst) begin
  if (rst) begin
    shift_reg <= 7'b0000001;
  end else begin
    shift_reg <= {shift_reg[5:0], shift_reg[6]^shift_reg[3]};
    if (ctrl1) begin
      shift_reg <= 7'b0000011;
    end else if (ctrl2) begin
      shift_reg <= 7'b0000111;
    end
  end
end

assign display = shift_reg;

endmodule

This module has a clock input and a reset input, as well as two control inputs. Using clock trigger, the module generates pseudo-random sequences according to the generation polynomial. As each clock edge rises, the sequence moves one bit to the left and calculates the value of the next bit. If RESET is high, the register is reset to its initial value. If ctrl1 or ctrl2 is high, the register is set to one of the four predefined non-zero initial values.

Finally, the generated pseudo-random sequence is output onto an eight-bit nixie tube to display the current sequence values. In this example, the display variable is used to output the current value in the shift register to the nixie tube.