fpga项目: m序列扩频分频器 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

1. 框图

image

2. 代码

代码层次结构如下

image

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/01/03 11:22:27
// Design Name: 
// Module Name: prbs_div_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module prbs_div_test(
    input clk,
    input rst_n,
    input [15:0] data_in,
    output reg [1:0] data_out
    );

wire [15:0] data_tmp;
assign data_tmp=data_in^16'b1010_1010_1010_1010;    //采用的是模3,比模4复杂。偶数数字之和,减去奇数数字之和。

reg [4:0] sum;    
integer i;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
    sum<=0;
else
    sum<=data_tmp[0]+data_tmp[1]+data_tmp[2]+data_tmp[3]+data_tmp[4]+data_tmp[5]+data_tmp[6]+data_tmp[7]+data_tmp[8]
    +data_tmp[9]+data_tmp[10]+data_tmp[11]+data_tmp[12]+data_tmp[13]+data_tmp[14]+data_tmp[15]+1;

always @(posedge clk or negedge rst_n)
    if(rst_n==0)
        data_out<=0;
    else
        case(sum)
            0,3,6,9,12,15: data_out=0;
            1,4,7,10,13,16: data_out=1;
            2,5,8,11,14,17: data_out=2;
        endcase   
    
endmodule   

module m_sequence(
    input clk,
    input rst_n,
    output reg [15:0] seq
    );
    
    always @(posedge clk or negedge rst_n) begin 
        if(!rst_n) 
            seq <= 16'b0001000100010001;
        else 
            seq <= {seq[14:0], seq[15]^seq[14]};
    end
endmodule

module divider(
    input clk,
    input rst_n,
    input [1:0] div_sel,
    output clk_out
    );

reg [6:0] cnt; 
wire [6:0] cnt_val;

assign cnt_val=(div_sel==2'b00)? 70:
               (div_sel==2'b01)? 71: 
                                 72;
always @(posedge clk or negedge rst_n)
    if(!rst_n) 
        cnt<=7'd0;
    else if(cnt==cnt_val)
        cnt<=7'd0;
    else
        cnt<=cnt+1;
        
assign clk_out=(cnt<cnt_val/2)? 1: 0;
   
endmodule

module prbs_divider(
    input clk,
    input rst_n,
    output clk_out
    );
    
wire [15:0] seq;
wire [1:0] data_out;
m_sequence u_m_sequence(
    .clk(clk_out),
    .rst_n(rst_n),
    .seq(seq)
    );

prbs_div_test u_prbs_div_test(
    .clk(clk),
    .rst_n(rst_n),
    .data_in(seq),
    .data_out(data_out)
    );
    
divider u_divider(
    .clk(clk),
    .rst_n(rst_n),
    .div_sel(data_out),
    .clk_out(clk_out)
    );    
    
endmodule



module tb;
reg rst_n;
reg clk;

initial begin
    rst_n=0;
    #100;
    rst_n=1;
end

initial begin
    clk=0;
    forever #10 clk=~clk;
end   

reg [15:0] data_in;
always @(posedge clk or negedge rst_n)
    if(rst_n==0)
        data_in<=0;
    else
        data_in<=$random%65535;


prbs_div_test u_prbs_div_test(
    .clk(clk),
    .rst_n(rst_n),
    .data_in(data_in)
    );

endmodule


module tb2;
reg rst_n;
reg clk;

initial begin
    rst_n=0;
    #100;
    rst_n=1;
end

initial begin
    clk=0;
    forever #10 clk=~clk;
end   

wire [15:0] seq;
wire [1:0] data_out;
m_sequence u_m_sequence(
    .clk(clk),
    .rst_n(rst_n),
    .seq(seq)
    );

prbs_div_test u_prbs_div_test(
    .clk(clk),
    .rst_n(rst_n),
    .data_in(seq),
    .data_out(data_out)
    );

endmodule


module tb3;
reg rst_n;
reg clk;

initial begin
    rst_n=0;
    #100;
    rst_n=1;
end

initial begin
    clk=0;
    forever #10 clk=~clk;
end   

prbs_divider u_prbs_divider(
    .clk(clk),
    .rst_n(rst_n),
    .clk_out(clk_out)
    );

endmodule

3. 仿真波形

image

4. Z7-Nano综合实现结果

image