问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

线性移位寄存器用于加扰与解扰的Verilog实现

创作时间:
作者:
@小白创作中心

线性移位寄存器用于加扰与解扰的Verilog实现

引用
CSDN
1.
https://blog.csdn.net/ChenLei_hust/article/details/144117804

线性反馈移位寄存器(LFSR)在通信系统中常用于数据加扰与解扰,其具有硬件实现简单、资源消耗少、伪随机性好等优点。本文将详细介绍LFSR的加解扰原理,并提供Verilog代码实现。

LFSR用于加解扰的原因

  1. 高效实现:LFSR硬件实现简单,资源消耗少。
  2. 伪随机性:生成的序列在统计上表现出良好的随机性,适合加扰需求。
  3. 可逆性:加扰和解扰使用相同的LFSR和初始状态,可以恢复原始数据。
  4. 简单反馈:通过XOR操作与反馈多项式结合,易于实现。
  5. 易同步:发送端和接收端同步容易,只要使用相同的初始状态。
  6. 抗干扰能力:生成的伪随机序列能有效抵抗干扰。

LFSR广泛应用于通信系统、加密、错误检测等领域,因其高效、可逆且具有较强的抗干扰能力。

加解扰原理图

Verilog代码实现

加扰模块代码

`timescale 1ns / 1ps
`define DLY #0
(* DowngradeIPIdentifiedWarnings="yes" *)
//***********************************Entity Declaration*******************************
module aurora_64b66b_0_SCRAMBLER_64B66B #
(
    parameter TX_DATA_WIDTH = 62
)
(
    // User Interface
    UNSCRAMBLED_SYNC_HEAD,
    SCRAMBLED_SYNC_HEAD,
    UNSCRAMBLED_DATA_IN,
    SCRAMBLED_DATA_OUT,
    DATA_VALID_IN,
    // System Interface
    USER_CLK,       
    SYSTEM_RESET
);

//***********************************Port Declarations*******************************
    // User Interface
    input   [1:0]                 UNSCRAMBLED_SYNC_HEAD;
    input   [0:(TX_DATA_WIDTH-1)] UNSCRAMBLED_DATA_IN;
    input                         DATA_VALID_IN;
    output  [(TX_DATA_WIDTH-1):0] SCRAMBLED_DATA_OUT;
    output  reg  [1:0]            SCRAMBLED_SYNC_HEAD;

    // System Interface
    input   USER_CLK;
    input   SYSTEM_RESET;

//***************************Internal Register Declarations******************** 
    integer                        i;
    reg     [57:0]                 poly;
    reg     [57:0]                 scrambler = 58'h155_5555_5555_5555;
    reg     [0:(TX_DATA_WIDTH-1)]  tempData = {TX_DATA_WIDTH{1'b0}};
    reg                            xorBit;

    reg     [(TX_DATA_WIDTH-1):0]  SCRAMBLED_DATA_OUT;

//*********************************Main Body of Code***************************
    always @(scrambler,UNSCRAMBLED_DATA_IN)
    begin
        poly = scrambler;
        for (i=0;i<=(TX_DATA_WIDTH-1);i=i+1)
        begin
            xorBit = UNSCRAMBLED_DATA_IN[i] ^ poly[38] ^ poly[57];
            poly = {poly[56:0],xorBit};
            tempData[i] = xorBit;
        end
    end
 
    //________________ Scrambled Data assignment to output port _______________    
always @(posedge USER_CLK)
begin
    if (DATA_VALID_IN)
    begin
        SCRAMBLED_DATA_OUT <= tempData;
        scrambler          <= poly;
        SCRAMBLED_SYNC_HEAD<= UNSCRAMBLED_SYNC_HEAD;
    end
end

 
          
endmodule

解扰模块代码

module descrambler(
    //Input
    input wire                      clk_195p3125M       ,
    input wire                      rst_n               ,
    input wire [0:62 - 1]           scrambled_data_in   ,
    input wire                      idle_b_check_en     ,

    //Output
    output logic [62 - 1:0]         unscrambled_data_out,
    output logic                    idle_b_check_result
);

//---
// Parameters
//---
    parameter POLY_WIDTH = 58;

//---
// Internal variables
//---
    logic [POLY_WIDTH-1:0]  poly        ;
    logic [POLY_WIDTH-1:0]  poly_temp   ;
    logic [0:62-1]          data_temp   ;
    logic                   xor_bit     ;

//---
// Implementation
//---
    always_comb begin
        poly_temp = poly;
        for(int i = 0;i < 62; i += 1)begin
            xor_bit = scrambled_data_in[i] ^ poly_temp[38] ^ poly_temp[57];
            poly_temp = {poly_temp[POLY_WIDTH-2:0],scrambled_data_in[i]};
            data_temp[i] = xor_bit;
        end
    end

    always_ff @(posedge clk_195p3125M or negedge rst_n)begin
        if(!rst_n)begin
            unscrambled_data_out    <= {62{1'b0}};
            poly                    <= {POLY_WIDTH{1'b1}};
        end
        else begin
            unscrambled_data_out    <= data_temp    ;
            poly                    <= poly_temp    ;
        end
    end

/********************************Check idle_b********************************/
    always_ff @( posedge clk_195p3125M or negedge rst_n ) begin : Check_idle_b
        if(!rst_n)begin
           idle_b_check_result <= 0;
        end
        else if(idle_b_check_en)begin
            if(unscrambled_data_out == {{6'h2C},{7{8'hBC}}})begin
                idle_b_check_result <= 1;
            end
            else begin
                idle_b_check_result <= 0;
            end
        end
        else begin
            idle_b_check_result <= idle_b_check_result;
        end
    end
endmodule

测试平台代码

`timescale 1ns / 1ps

module testbench_scrambler_descrambler;

    // Parameters
    parameter TX_DATA_WIDTH = 62;
    parameter POLY_WIDTH = 58;

    // Inputs and Outputs for Scrambler
    reg                         clk;
    reg                         rst_n;
    reg  [1:0]                  unscrambled_sync_head;
    reg  [TX_DATA_WIDTH-1:0]    unscrambled_data_in;
    reg                         data_valid_in;
    wire [TX_DATA_WIDTH-1:0]    scrambled_data_out;
    wire [1:0]                  scrambled_sync_head;

    // Inputs and Outputs for Descrambler
    reg                         idle_b_check_en;
    wire [TX_DATA_WIDTH-1:0]    descrambled_data_out;
    wire                        idle_b_check_result;

    // Instantiate Scrambler
    aurora_64b66b_0_SCRAMBLER_64B66B #(
        .TX_DATA_WIDTH(TX_DATA_WIDTH)
    ) uut_scrambler (
        .UNSCRAMBLED_SYNC_HEAD(unscrambled_sync_head),
        .SCRAMBLED_SYNC_HEAD(scrambled_sync_head),
        .UNSCRAMBLED_DATA_IN(unscrambled_data_in),
        .SCRAMBLED_DATA_OUT(scrambled_data_out),
        .DATA_VALID_IN(data_valid_in),
        .USER_CLK(clk),
        .SYSTEM_RESET(!rst_n)
    );

    // Instantiate Descrambler
    descrambler uut_descrambler (
        .clk_195p3125M(clk),
        .rst_n(rst_n),
        .scrambled_data_in(scrambled_data_out),
        .idle_b_check_en(idle_b_check_en),
        .unscrambled_data_out(descrambled_data_out),
        .idle_b_check_result(idle_b_check_result)
    );

    // Clock Generation
    initial begin
        clk = 0;
        forever #5 clk = ~clk; // 100 MHz clock
    end

    // Test Sequence
    initial begin
        // Initialize signals
        rst_n = 0;
        unscrambled_sync_head = 2'b00;
        unscrambled_data_in = 0;
        data_valid_in = 0;
        idle_b_check_en = 0;

        // Apply reset
        #20 rst_n = 1;

        // Test case 1: Transmit random data
        #10 unscrambled_sync_head = 2'b01;
            unscrambled_data_in = 62'h3FFFFFFFFFFFFF;
            data_valid_in = 1;

        #10 unscrambled_data_in = 62'h123456789ABCDE;

        #10 unscrambled_data_in = 62'h55555555555555;

        #10 data_valid_in = 0;

        // Enable idle_b_check for descrambler
        #10 idle_b_check_en = 1;

        // Wait for descrambler to process data
        #100;

        // Test case 2: Transmit known pattern
        unscrambled_data_in = 62'hA5A5A5A5A5A5A5;
        unscrambled_sync_head = 2'b10;
        data_valid_in = 1;

        #10 data_valid_in = 0;

        // Check idle_b_check_result
        #10 idle_b_check_en = 0;

        // Finish simulation
        #50 $stop;
    end

    // Monitor outputs
    initial begin
        $monitor($time, 
            " Unscrambled Data In = %h, Scrambled Data Out = %h, Descrambled Data Out = %h, Check Result = %b", 
            unscrambled_data_in, scrambled_data_out, descrambled_data_out, idle_b_check_result);
    end

endmodule

仿真结果

(此处省略仿真结果图片,实际应用中应包含仿真波形图)

总结

LFSR加解扰的本质是在加扰和解扰时保持内部寄存器状态一致,通过两次异或操作恢复原始数据。这种机制在通信系统中得到广泛应用,特别是在需要数据加扰以改善信号传输特性的场景中。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号