parameter length_in = 1'b0;
//==================得到下一状态的输入值=====================
assign exp_out[00] = (exp_in[00] & poly_in[06]) ^ (exp_in[01] & poly_in[05]) ^ (exp_in[02] & poly_in[04]) ^ (exp_in[03] & poly_in[03]) ^ (exp_in[04] & poly_in[02]) ^ (exp_in[05] & poly_in[01]) ^
(exp_in[06] & poly_in[00]) ^ length_in;
//由特征多项式得到下一状态的输入值
assign exp_out[06:01] = exp_in[05:00];//当前状态值移位得到下一状态值 //=================更新状态并将数据输出=======================
always @ (posedge clock_in) begin if (reset_in) begin
exp_in <= 7'b1111111; //给寄存器赋初值 data_out <= 1; end
else begin
exp_in <= exp_out;
data_out <= exp_out[06]; //输出值 end end endmodule
在上述程序中,首先值得注意是Poly这个参数定义,它根据特征多项式转化而来,这样定义可以更方便的得到下一状态的输出值。系统将当前寄存器的状态值与该参数相与,并将各位异或,实现的即为寄存器外部的异或,由此得到的便是下一状态的输入值。将当前状态值移位便得到下一状态各寄存器的值。
还有一点要注意的是,在系统进行复位之后,必须给寄存器赋初值,否则输出序列是不定值。
移位寄存器输出的是串行数据,在实际应用中常常需要并行的伪随机序列,用户只需根据自己的需要,循环调用此模块,并用N x M位(其中N表示并行数据的宽度,M表示伪随机序列的阶数)的寄存器进行存储,在同一时刻便可输出并行的伪随机码。 3.2.1.1 仿真分析
代码在ISE软件中综合之后,进行功能仿真。其仿真波形如图4所示:
图4 伪随机序列仿真图
在复位信号reset_in之后,系统自动启动,正常工作,第一行的data_out即为串行输出的伪随机序列。
在ISE上综合并且功能仿真通过之后,还需在开发板是进行调试,以验证程序实际运行的效果。调试时采用开发板上100MHZ的固定时钟作为设计时钟输入,故在工程中要注意对时钟进行约束,否则程序无法在开发板上运行。
本设计采用chipscope逻辑分析仪进行调试,调试需要使用到三个核:ICON、ILA和VIO核。ICON为控制内核,其控制端口为2,分别控制ILA核和VIO 核。ILA核用于观察伪随机序列输出的波形,触发端口为1位。VIO核输入输出信号进行设置,异步输出控制复位信号,1位宽;异步输入观察输出的数据,1位宽。图5为生成VIO核时的设置:
图5 VIO核的设置
图5中选中的是异步输入输出,位宽都是1位长。其它核的生成方法类似,按照前面所述进行设置即可。
最后添加的chipscope调试代码如下:
wire [35:0] control_ila,control_vio;
wire async_in;
wire async_out;
wire reset_in; wire trig0;
assign reset_in = async_out; assign async_in = data_out; assign trig0 = data_out;
icon i_icon(
.CONTROL0(control_ila), .CONTROL1(control_vio) );
vio i_vio(
.CONTROL(control_vio),
.ASYNC_OUT(async_out), .ASYNC_IN(async_in)
);
ila i_ila(
.CLK(clock_in), .CONTROL(control_ila), .TRIG0(trig0) );
其中,reset_in是系统的复位信号,由async_out控制;data_out是输出的数据,由trig0可观察到该信号的波形。
图6为VIO核的调试界面:
图6 VIO核界面
图中reset_in为复位信号,data_out为输出的数据。
图7为最后ILA核呈现的波形界面:
图7 ILA核调试波形
从图7中可以看到,伪随机码的波形与功能仿真的波形一致。
3.2.2伽罗瓦方式
伽罗瓦(Galoris)V代码如下:
module wsj_2( data_out, clock_in, reset_in ); output data_out; // 输入输出声明
input clock_in, reset_in;
//=========================变量声明========================= wire [06:00] exp_out; //下一状态各寄存器存储的值,其最高位为下一
//次触发时的输出值
reg [06:00] exp_in; reg data_out;
parameter poly_in = 07'h03;//poly为特征多项式转化而来的7位值,
//若为‘1’,表示此处需要或门
//Poly : x^7 + x^6
// : 000 0011
// : 0 3
parameter length_in = 1'b0;
//=======================得到下一状态的输入值=================== //由特征多项式得到下一状态的输入值
assign exp_out[00] = length_in ^ (exp_in[06] & poly_in[00]); assign exp_out[01] = exp_in[00] ^ (exp_in[06] & poly_in[01]); assign exp_out[02] = exp_in[01] ^ (exp_in[06] & poly_in[02]); assign exp_out[03] = exp_in[02] ^ (exp_in[06] & poly_in[03]); assign exp_out[04] = exp_in[03] ^ (exp_in[06] & poly_in[04]); assign exp_out[05] = exp_in[04] ^ (exp_in[06] & poly_in[05]); assign exp_out[06] = exp_in[05] ^ (exp_in[06] & poly_in[06]); //===================更新状态并将数据输出===================== always @ (posedge clock_in) begin if (reset_in) begin exp_in <= 7'b1111111; data_out <= 1; end
else begin
exp_in <= exp_out; data_out <= exp_out[06];