Menu Close

高速通信中的信道编码–加扰与解扰

在上节内容中讲解了串行通信中的帧结构,如每个帧的开始部分都会有前导字和帧起始(即Preamble+SFD)作为帧的标志,在帧同步时作为同步字搜索,接收端可以在搜索到关键字后进行帧同步。这个前导字不仅能提供短暂的直流平衡,还能提供足够的时钟信息,在位同步的解调中起到关键的作用。在自适应位同步的提取中(ACDR),有一个前提是在帧数据部分也应该有足够的边沿变化,而在源码的数据流中长0或长1的概率是非常高的,因此就要将通信中的源码进行变换,通常称为编码。这种用于改善信道的编码称为信道编码。信道编码通常有如下几种,加扰,4b/5b编码,8b/10b编码,64b/66b编码,128b/130b, 128b/132b等,其它几种编码已经在其它章节介绍过了,本节内容着重讲解加扰(Scrambler)编码以及其反变换–解扰(de-scrambler)等原理及使用。

1.  加扰

加扰的原理是在数据串行化时将串行数据流送入加扰器,通过加扰器的模2运算(异或运算)使得长0与长1消除。关于加扰的原理的相关知识,可以参考相关内容。加扰又分为两种,加性加扰和乘性加扰两种。加性加扰如图1所示,

图1 加性加扰器

  • 加性加扰

加性加扰的特点是加扰器产生的模2运算的结果与输入数据再做模2运算,结果作为串行数据输出。加性加扰器有如下内容及特点:

(1)典型生成多项式 ,

G(X) = X15 + X14 + 1

G(X) = X23 + X18 + 1

(2) 运算前需要同步,即在一帧数据发送前应初始化加扰器如图1,在帧数据加扰前应将加扰器的寄存器初始化为1001_0101_0000_000, 例如

                  reg [14:0] sramb_sync = 15’b000_0000_1010_1001;

(3)输入数据不参与加扰器的寄存器移位,仅加扰器自身的模2加结果参与循环移位

(4)解扰器的生成多项式即运算过程与加扰器一致如图1,解扰器也需要帧初始化同步。同步控制一般采用帧起始(如preamble+SFD)或64b/66b的中66-bit的控制位(如01或10, 详细内容请参照64b/66b的内容).

 

例1, 利用生成多项式G(X) = X15 + X14 + 1 实现加性加扰与解码Verilog代码,并通过Modelsim进行验证。

发送端代码:

`timescale 1 ns /1 ps

module additive_scrambler_tx#
(
    parameter SCRAMB_SYNC = 15'b000_0000_1010_1001
)
(
    input sys_clk,
    input rst,
    input tx_start,
    input tx_en,
    input [ 7: 0 ] tx_data,
    input tx_end,
    output reg tx_rdy,
    output reg tx_out
);

reg [ 14: 0 ] scrambler;
reg [ 7: 0 ] tx_shift;
reg [ 3: 0 ] shift_count;
wire scb_bit;
reg tx_end_r;
reg tx_end_ack;


always@( posedge sys_clk or posedge rst )
    if ( rst )
        tx_end_r <= 0;
    else
    begin
        if ( tx_end )
            tx_end_r <= 1'b1;
        else if ( tx_end_ack )
            tx_end_r <= 1'b0;
    end


reg [ 2: 0 ] scb_st;

assign scb_bit = scrambler[ 14 ] ^ scrambler[ 13 ];

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        scb_st <= 0;
        scrambler <= SCRAMB_SYNC;
        tx_shift <= 0;
        shift_count <= 0;
        tx_rdy <= 0;
        tx_end_ack <= 0;
    end
    else
    begin
        case ( scb_st )
            0:
            begin
                tx_rdy <= 1'b0;
                tx_end_ack <= 0;
                if ( tx_start )
                begin
                    scb_st <= 1;
                    scrambler <= SCRAMB_SYNC;
                end
            end
            1:
            begin
                tx_rdy <= 1'b1;
                shift_count <= 0;
                if ( tx_end )
                    scb_st <= 0;
                else if ( tx_en )
                begin
                    tx_shift <= tx_data;
                    shift_count <= shift_count + 1;
                    tx_rdy <= 1'b0;
                    scb_st <= 2;
                end
            end
            2:
            begin
                tx_rdy <= 0;
                scrambler <= { scrambler[ 13: 0 ], scb_bit };
                if ( tx_en )
                begin
                    tx_shift <= tx_data;
                end
                else
                    tx_shift <= { 1'b1, tx_shift[ 7: 1 ] };

                if ( shift_count == 6 )
                    tx_rdy <= 1'b1;
                if ( shift_count == 7 )
                begin
                    shift_count <= 0;
                    if ( tx_end_r )
                    begin
                        scb_st <= 0;
                        tx_end_ack <= 1;
                    end
                end
                else
                    shift_count <= shift_count + 1;
            end
            default:
                scb_st <= 0;
        endcase
    end


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        tx_out <= 1'b1;
    end
    else
    begin
        tx_out <= tx_shift[ 0 ] ^ scb_bit;
    end


endmodule

 

接收端代码:

`timescale 1 ns /1 ps

module additive_scrambler_rx#
(
    parameter SCRAMB_SYNC = 15'b000_0000_1010_1001
)
(
    input sys_clk,
    input rst,
    input rx_start,
    input rx_en,
    input rx_in,
    input rx_end,
    output reg rx_rdy,
    output reg [ 7: 0 ] rx_data
);

reg [ 14: 0 ] scrambler;
reg [ 7: 0 ] rx_shift;
reg [ 3: 0 ] shift_count;
wire scb_bit;
wire rx_bit;
reg rx_rdy_tmp;
reg rx_end_r;
reg rx_end_ack;

reg [ 2: 0 ] scb_st;

assign scb_bit = scrambler[ 14 ] ^ scrambler[ 13 ];
assign rx_bit = rx_in ^ scb_bit;


always@( posedge sys_clk or posedge rst )
    if ( rst )
        rx_end_r <= 0;
    else if ( rx_end )
        rx_end_r <= 1'b1;
    else if ( rx_end_ack )
        rx_end_r <= 1'b0;


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        scb_st <= 0;
        scrambler <= SCRAMB_SYNC;
        rx_shift <= 0;
        shift_count <= 0;
        rx_rdy_tmp <= 0;
        rx_end_ack <= 1'b0;
    end
    else
    begin
        case ( scb_st )
            0:
            begin
                rx_rdy_tmp <= 0;
                rx_end_ack <= 1'b0;
                if ( rx_start )
                begin
                    scb_st <= 1;
                    scrambler <= SCRAMB_SYNC;
                end
            end
            1:
            begin
                rx_rdy_tmp <= 0;
                if ( rx_end )
                    scb_st <= 0;
                else if ( rx_en )
                begin
                    scb_st <= 2;
                end
            end
            2:
            begin
                rx_rdy_tmp <= 1'b0;
                scrambler <= { scrambler[ 13: 0 ], scb_bit };
                rx_shift <= { rx_bit, rx_shift[ 7: 1 ] };
                if ( shift_count == 7 )
                begin
                    shift_count <= 0;
                    rx_rdy_tmp <= 1'b1;

                    if ( rx_end_r )
                    begin
                        rx_end_ack <= 1'b1;
                        scb_st <= 0;
                    end
                end
                else
                    shift_count <= shift_count + 1;
            end
            default:
                scb_st <= 0;
        endcase

    end


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        rx_data <= 0;
        rx_rdy <= 0;
    end
    else
    begin
        rx_rdy <= rx_rdy_tmp;
        if ( rx_rdy_tmp )
        begin
            rx_data <= rx_shift;
        end
    end



endmodule

 

发送接收组装代码:

`timescale 1 ns /1 ps

module additive_scrambler#
(
    parameter SCRAMB_SYNC = 15'b000_0000_1010_1001
)
(
    input sys_clk,
    input rst,
    input tx_start,
    input tx_en,
    input [ 7: 0 ] tx_data,
    input tx_end,
    output tx_rdy,
    output [ 7: 0 ] rx_data,
    output rx_rdy
);


wire tx_out;
reg rx_en;
wire rx_in = tx_out;   //回环测试

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        rx_en <= 0;
    end
    else
    begin
        if ( tx_end )
            rx_en <= 0;
        else if ( tx_en )
            rx_en <= 1'b1;
    end

additive_scrambler_tx#
(
    .SCRAMB_SYNC( 15'b000_0000_1010_1001 )
)
additive_scrambler_tx_inst
(
    .sys_clk  ( sys_clk ),
    .rst      ( rst ),
    .tx_start ( tx_start ),
    .tx_en    ( tx_en ),
    .tx_data  ( tx_data ),
    .tx_end   ( tx_end ),
    .tx_rdy   ( tx_rdy ),
    .tx_out   ( tx_out )
);


additive_scrambler_rx#
(
    .SCRAMB_SYNC( 15'b000_0000_1010_1001 )
)
additive_scrambler_rx_inst
(
    .sys_clk  ( sys_clk ),
    .rst      ( rst ),
    .rx_start ( tx_start ),
    .rx_en    ( rx_en ),
    .rx_in    ( rx_in ),
    .rx_end   ( tx_end ),
    .rx_data  ( rx_data ),
    .rx_rdy   ( rx_rdy )
);

endmodule

 

仿真代码:

`timescale 1 ns /1 ps

module tb ( );
parameter sramb_sync = 15'b000_0000_1010_1001;

reg sys_clk = 0;

always #5 sys_clk = ~sys_clk;

reg rst = 1'b1;

initial
begin
    rst = 1'b1;
    #15 rst = 1'b0;
end

wire [ 7: 0 ] rx_data;
wire rx_rdy;
//=====================additive scambler
wire tx_rdy;
reg [ 7: 0 ] tx_data;
reg tx_start;
reg tx_en;
reg tx_end;
reg [ 4: 0 ] tx_delay;
reg [ 7: 0 ] tx_count;
reg [ 1: 0 ] tx_st;

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        tx_data <= 0;
        tx_count <= 0;
        tx_en <= 0;
        tx_start <= 0;
        tx_delay <= 0;
        tx_end <= 0;
        tx_st <= 0;
    end
    else
    begin
        case ( tx_st )
            0:
            begin
                tx_start <= 1'b1;
                tx_data <= 0;
                tx_count <= 0;
                tx_en <= 0;
                tx_delay <= 0;
                tx_st <= 1;
            end
            1:
            begin
                tx_start <= 1'b0;
                if ( tx_rdy )
                begin
                    tx_count <= tx_count + 1;
                    tx_en <= 1'b1;
                    tx_st <= 2;
                end
            end
            2:
            begin
                tx_en <= 0;
                if ( tx_count == 32 )
                begin
                    tx_end <= 1'b1;
                    tx_st <= 3;
                end
                else
                begin
//                    tx_count <= tx_count + 1;
                    tx_st <= 1;
                end

                if ( tx_count < 8 )
                    tx_data <= 0;
                else if ( tx_count > 23 )
                    tx_data <= 8'hff;
                else
                    tx_data <= tx_count;

            end
            3:
            begin
                tx_end <= 0;
                if ( tx_delay == 31 )
                    tx_st <= 0;
                else
                    tx_delay <= tx_delay + 1;
            end

        endcase
    end



additive_scrambler#
(
    .SCRAMB_SYNC( 15'b000_0000_1010_1001 )
)
additive_scrambler_inst
(
    .sys_clk  ( sys_clk ),
    .rst      ( rst ),
    .tx_start ( tx_start ),
    .tx_en    ( tx_en ),
    .tx_data  ( tx_data ),
    .tx_end   ( tx_end ),
    .tx_rdy   ( tx_rdy ),
    .rx_data  ( rx_data ),
    .rx_rdy   ( rx_rdy )

);

endmodule

 

 

图1    tb仿真波形

图1  可以看出在加扰后接系统能正确解扰收发端的加扰数据,详细的加扰效果可以参考图2。

 

图2

图2 中显示了发送程序的加扰效果,红色框中在tx_data在一段时间都为0,但tx_out信号经过加扰后,出现0,1交替输出。

 

图3

图3中可以观察到在接收端rx_in, scb_bit, rx_bit之间的运算,以及scrambler 的移位过程。

上面的例子主要目的是演示了加扰后对发送串行流带来的效果,如图2, 同时对于加性加扰如何根据帧同步控制加扰器进行复位初始化,以及在发送和接收中实现加扰/解扰器的移位。在实际的异步通信中可以用Preamble+SFD实现帧同步,或采用64b/66b的2位控制字实现同步。

  • 乘性加扰

与加性加扰不同的是乘性加扰不仅加扰器自身模2加后循环移位,而且输入数据流也参与模2运算后参与加扰计算,从这一点看数据流的输出与输入之间(历史数据)有相与的关系存在,因此称为乘性加扰。生成多项式为G(X) = X23 + X18 + 1的加扰器如图4所示。

乘性加扰是递归的。即加扰后的信号反馈到移位回路中。

图4

  • 乘性解扰

与加性解扰不同,乘性解扰不需要同步和初始化,但乘性解扰不能使用加扰器进行解扰,这一点与加性加扰器有重大区别,从上的加性加扰和解扰可以看出,加性加扰与解扰使用同一套加扰器。而乘性解扰则是独立的逻辑电路,如图5所示。

图5

解扰器的特点是非递归的,即解扰后的信号不反馈到回路中去。

2 .乘性加扰与加性加扰相比有如下异同点:

    • 加性加扰需要特定初始化值,乘性加扰不需要特定初始化值(可以为随机数)。
    • 加性加扰需要同步复位,乘性加扰不需要同步复位
    • 加性加扰器也加性解扰器,乘性加扰与解扰分别为不同时序逻辑电路,但生成多项式相同。
    • 加性加扰循环移位寄存器不受输入信号的影响是移位寄存器模2运算移位的结果,乘性加扰器的输入参与模2运算并前馈到移位序列中,历史输入数据参与加扰运算。
    • 乘性加扰由于不需要同步复位,因此在加扰和解扰时的逻辑设计相对简单。

3. 乘性加扰与解扰编程与测试

(1) 发送端乘性加扰物理层(phy)的代码mul_scrambler_phy.v

`timescale 1 ns /1 ps

module mul_scrambler_phy
(
    input rst,
    input sys_clk,
    input tx_in,
    output reg tx_out
);

reg [ 22: 0 ] scb_shift;

wire tx_tmp = tx_in ^ ( scb_shift[ 17 ] ^ scb_shift[ 22 ] );

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        scb_shift <= 0;
        tx_out <= 0;
    end
    else
    begin
        tx_out <= tx_tmp;
        scb_shift <= { scb_shift[ 21: 0 ], tx_tmp };

    end

endmodule

 

(2)接收端端乘性加扰物理层(phy)的代码mul_scrambler_phy.v

`timescale 1 ns /1 ps

module mul_descrambler_phy
(
    input rst,
    input sys_clk,
    input rx_in,
    output reg rx_out
);


reg [ 22: 0 ] scb_shift;
wire rx_tmp = rx_in ^ ( scb_shift[ 17 ] ^ scb_shift[ 22 ] );

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        scb_shift <= 0;
        rx_out <= 0;
    end
    else
    begin
        rx_out <= rx_tmp;
        scb_shift <= { scb_shift[ 21: 0 ], rx_in };
    end

endmodule

 

(3)发送端数据帧及串行化mul_scrambler.v

`timescale 1 ns /1 ps

module mul_scrambler#
(
    parameter SYNC_PREABLE = 8'b1010_1010,
    parameter SYNC_SFD = 8'b1010_1011
)

(
    input rst,
    input sys_clk,
    input tx_start,
    input [ 7: 0 ] tx_data,
    input tx_en,
    input tx_end,
    output reg tx_rdy_r,
    output tx_out
);

reg [ 7: 0 ] tx_data_r;
reg [ 7: 0 ] tx_sht;

reg [ 2: 0 ] tx_sht_count;

reg [ 2: 0 ] tx_st;

wire tx_bit = tx_sht[ 7 ];

reg tx_start_r;
reg tx_start_ack;

reg tx_en_r;
reg tx_en_ack;

reg tx_end_r;
reg tx_end_ack;
reg tx_rdy;


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        tx_start_r <= 0;
        tx_end_r <= 0;
        tx_en_r <= 0;
        tx_rdy_r <= 0;
    end
    else
    begin

        if ( tx_start )
            tx_start_r <= 1'b1;
        else if ( tx_start_ack )
            tx_start_r <= 1'b0;


        if ( tx_end )
            tx_end_r <= 1'b1;
        else if ( tx_end_ack )
            tx_end_r <= 1'b0;


        if ( tx_en )
            tx_en_r <= 1'b1;
        else if ( tx_en_ack )
            tx_en_r <= 0;

        tx_rdy_r <= tx_rdy;

    end


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        tx_data_r <= SYNC_PREABLE;
        tx_sht <= SYNC_PREABLE;
        tx_sht_count <= 0;
        tx_rdy <= 1'b0;
        tx_start_ack <= 0;
        tx_end_ack <= 1'b0;
        tx_en_ack <= 1'b0;
        tx_st <= 0;
    end
    else
    begin

        case ( tx_st )
            0:
            begin
                tx_data_r <= SYNC_PREABLE;
                tx_sht <= tx_data_r;
                tx_sht_count <= 0;
                tx_rdy <= 1'b0;
                tx_start_ack <= 0;
                tx_end_ack <= 1'b0;
                tx_en_ack <= 1'b0;
                tx_st <= 1;
            end
            1:
            begin
                tx_rdy <= 1'b0;

                if ( tx_sht_count == 7 )
                begin
                    tx_sht <= tx_data_r;
                    tx_sht_count <= 0;

                    if ( tx_start_r )
                    begin
                        tx_data_r <= SYNC_SFD;
                        tx_start_ack <= 1'b1;
                        tx_en_ack <= 1'b1;
                        tx_rdy <= 1'b1;
                        tx_st <= 2;
                    end
                end
                else
                begin
                    tx_sht <= { tx_sht[ 6: 0 ], 1'b0 };
                    tx_sht_count <= tx_sht_count + 1'b1;
                end
            end
            2:
            begin
                tx_en_ack <= 1'b0;
                tx_rdy <= 1'b0;
                tx_start_ack <= 1'b0;

                if ( tx_sht_count == 7 )
                begin
                    tx_sht <= tx_data_r;
                    tx_sht_count <= 0;

                    if ( tx_en_r )
                    begin
                        tx_en_ack <= 1'b1;
                        tx_data_r <= tx_data;
                        tx_rdy <= 1'b1;
                    end
                    else if ( tx_end_r )
                    begin
                        tx_end_ack <= 1'b1;
                        tx_en_ack <= 1'b1;
                        tx_data_r <= SYNC_PREABLE;
                        tx_sht <= SYNC_PREABLE;
                        tx_st <= 0;
                    end
                end
                else
                begin
                    tx_sht <= { tx_sht[ 6: 0 ], 1'b0 };
                    tx_sht_count <= tx_sht_count + 1'b1;
                end
            end
            default:
                tx_st <= 0;
        endcase
    end


mul_scrambler_phy mul_scrambler_phy
(
    .rst     ( rst ),
    .sys_clk ( sys_clk ),
    .tx_in   ( tx_bit ),
    .tx_out  ( tx_out )
);

endmodule

 

 

(4)接收端串并转换及数据帧mul_descrambler.v

`timescale 1 ns /1 ps

module mul_descrambler#
(
    parameter SYNC_PREABLE = 8'b1010_1010,
    parameter SYNC_SFD = 8'b1010_1011
)
(
    input rst,
    input sys_clk,
    input rx_in,
    output reg[ 7: 0 ] rx_data,
    output reg rx_rdy,
    output reg fr_end
);


wire rx_out;

reg [ 4: 0 ] rx_count;
reg [ 2: 0 ] rx_bit_count;

reg [ 7: 0 ] bit_sft;
reg [ 7: 0 ] sync_shift;
reg fr_sync;


always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin

        bit_sft <= 0;
        sync_shift <= 0;
        rx_data <= 0;
        rx_rdy <= 1'b0;
        rx_bit_count <= 0;
        rx_count <= 0;
        fr_sync <= 0;
        fr_end <= 0;
    end
    else
    begin

        bit_sft <= { bit_sft[ 6: 0 ], rx_out };
        sync_shift <= { sync_shift[ 6: 0 ], bit_sft[ 7 ] };

        if ( fr_end )
        begin
            fr_sync <= 1'b0;
        end
        else if ( ( bit_sft == SYNC_SFD ) && ( sync_shift == SYNC_PREABLE ) )
            fr_sync <= 1'b1;

        rx_rdy <= 1'b0;

        if ( fr_sync )
        begin
            if ( rx_bit_count == 7 )
            begin
                rx_rdy <= 1'b1;
                rx_data <= bit_sft;
                rx_bit_count <= 0;
            end
            else
                rx_bit_count <= rx_bit_count + 1;
        end

        fr_end <= 0;
        if ( fr_end )
            rx_bit_count <= 0;
        else if ( rx_rdy )
        begin
            if ( rx_count == 31 )
            begin
                rx_count <= 0;
                fr_end <= 1'b1;
            end
            else
                rx_count <= rx_count + 1;
        end

    end


mul_descrambler_phy mul_descrambler_phy_inst
(
    .rst        ( rst ),
    .sys_clk    ( sys_clk ),
    .rx_in      ( rx_in ),
    .rx_out     ( rx_out )
);


endmodule

 

(5)收发合并comp_mul_scrabler.v

`timescale 1 ns /1 ps
module comp_mul_scrabler#
(
    parameter SYNC_PREABLE = 8'b1010_1010,
    parameter SYNC_SFD = 8'b1010_1011
)
(
    input rst,
    input sys_clk,
    input tx_start,
    output tx_rdy,
    input [ 7: 0 ] tx_data,
    input tx_en,
    input tx_end,

    output rx_vld,
    output[ 7: 0 ] rx_data,
    output rx_rdy,
    output fr_end
);

wire tx_bit;

mul_scrambler#
(
    .SYNC_PREABLE( SYNC_PREABLE ),
    .SYNC_SFD ( SYNC_SFD )
)
mul_scrambler_inst
(
    .rst        ( rst ),
    .sys_clk    ( sys_clk ),
    .tx_start   ( tx_start ),
    .tx_data    ( tx_data ),
    .tx_en      ( tx_en ),
    .tx_end     ( tx_end ),
    .tx_rdy_r   ( tx_rdy ),
    .tx_out     ( tx_bit )
);


mul_descrambler#
(
    .SYNC_PREABLE( SYNC_PREABLE ),
    .SYNC_SFD ( SYNC_SFD )
)
mul_descrambler_inst
(
    .rst        ( rst ),
    .sys_clk    ( sys_clk ),
    .rx_in      ( tx_bit ), //  feedback loop
    .rx_data    ( rx_data ),
    .fr_end     ( fr_end ),
    .rx_rdy     ( rx_rdy )
);


endmodule

 

(6)仿真程序tb.v

`timescale 1 ns /1 ps

module tb ( );
parameter sramb_sync = 15'b000_0000_1010_1001;

reg sys_clk = 0;

always #5 sys_clk = ~sys_clk;

reg rst = 1'b1;

initial
begin
    rst = 1'b1;
    #15 rst = 1'b0;
end

wire [ 7: 0 ] rx_data;
wire rx_rdy;
//=====================additive scambler
wire tx_rdy;
reg [ 7: 0 ] tx_data;
reg tx_start;
reg tx_en;
reg tx_end;
reg [ 4: 0 ] tx_delay;
reg [ 7: 0 ] tx_count;
reg [ 1: 0 ] tx_st;

always@( posedge sys_clk or posedge rst )
    if ( rst )
    begin
        tx_data <= 0;
        tx_count <= 0;
        tx_en <= 0;
        tx_start <= 0;
        tx_delay <= 0;
        tx_end <= 0;
        tx_st <= 0;
    end
    else
    begin
        case ( tx_st )
            0:
            begin
                tx_start <= 1'b1;
                tx_data <= 0;
                tx_count <= 0;
                tx_en <= 0;
                tx_delay <= 0;
                tx_st <= 1;
            end
            1:
            begin
                tx_start <= 1'b0;
                if ( tx_rdy )
                begin
                    tx_en <= 1'b1;
                    tx_st <= 2;
                end
            end
            2:
            begin
                tx_en <= 0;
                if ( tx_count == 32 )
                begin
                    tx_end <= 1'b1;
                    tx_st <= 3;
                end
                else
                begin
                    tx_count <= tx_count + 1;
                    tx_st <= 1;
                end

                if ( tx_count < 8 )
                    tx_data <= 0;
                else if ( tx_count > 23 )
                    tx_data <= 8'hff;
                else
                    tx_data <= tx_count;

            end
            3:
            begin
                tx_end <= 0;
                if ( tx_delay == 31 )
                    tx_st <= 0;
                else
                    tx_delay <= tx_delay + 1;
            end

        endcase
    end



additive_scrambler#
(
    .SCRAMB_SYNC( 15'b000_0000_1010_1001 )
)
additive_scrambler_inst
(
    .sys_clk    ( sys_clk ),
    .rst        ( rst ),
    .tx_start   ( tx_start ),
    .tx_en      ( tx_en ),
    .tx_data    ( tx_data ),
    .tx_end     ( tx_end ),
    .tx_rdy     ( tx_rdy ),
    .rx_data    ( rx_data ),
    .rx_rdy     ( rx_rdy )
);

endmodule

 

 

(7) 仿真波形

图6  tb.v的仿真波形

图7  mul_scrambler.v  仿真波形

图8  mul_descrambler.v的仿真波形

乘性加扰及解扰工程代码下载:

[content_control]

additive_scrambler.ZIP

[/content_control]

注:加性加扰,将上文中的第一个tb.v替代工程中的tb.v文件即可测试加性加扰/解扰的Verilog RTL 代码。更详细的解释请看对应的视频文件。

Posted in FPGA, FPGA 教材教案, IC, IP开发, 教材与教案, 文章

发表回复

相关链接