课程设计内容,用Verilog写一个A5/1对称式流密码器
功能阐述:本次设计的是对称式流密码器,若输入明文则输出密文,输入密文则输出明文,加密和解密的处理过程都一样。设置处理数据为十六位二进制数,输入待处理数据,按下启动键,就能获得待处理数据
设计思路:使用一个三段式FSM状态机来作为控制单元,状态图在下方,分为两个状态,一个是初态,一个是加密态。引进一个计数器作为辅助,从初态进入加密态,计数器启动计数,每个时钟周期生成一位密码流,加密/解密1位二进制数,计数1次,计数达到16次结束数据处理回到初态并显示处理完成的数据,现态转回初态,计数器归零。 设计的是经典的三段式状态机,第一段是输出逻辑部分,包含两个always块,一个用于密钥的线性反馈移位和加密数据,由时钟信号触发,另外一个用于密钥移位后获取下一位密码流,由密钥的变动触发;第二段是次态计算部分,每当有变量产生变动时,就根据现态来决定次态,属于组合逻辑;第三段是次态转换部分,当时钟信号来临,将次态赋值给现态
核心代码:
模块连接和外部接口模块文件Virtual_Lab_Top.v:
//A5/1密码器
`default_nettype none
module Virtual_Lab_Top
(
input wire CLOCK,
input wire [4:0] BUTTON, //按键
input wire [35:0] SWITCH, //开关
output wire [35:0] LED, //指示灯
output wire [3:0] HEX0, //数码管
output wire [3:0] HEX1,
output wire [3:0] HEX2,
output wire [3:0] HEX3
);
//输入端口赋值给内部信号
wire [15:0] IN = SWITCH[15:0]; //需加/解密的输入数据
wire start_asyn = BUTTON[0]; //启动信号
wire _reset = BUTTON[1]; //重置信号
reg start; //启动信号定义
wire done; //完成信号定义
wire [15:0] OUT; //加/解密完成的输出数据信号定义
//启动信号
always@(posedge CLOCK or posedge _reset or posedge done)
begin
if(_reset==1 || done==1)
start<=1'b0;
else
start<= start_asyn;
end
//连接FSM控制模块
FSM_controller u1(CLOCK,_reset,start,IN,OUT,done);
//内部信号赋值给输出端口(数码管)观察
assign HEX0 = OUT[3:0];
assign HEX1 = OUT[7:4];
assign HEX2 = OUT[11:8];
assign HEX3 = OUT[15:12];
endmodule
FSM状态机控制单元模块文件FSM_controller.v:
//-----------A5/1密码器-----------
//FSM控制单元
module FSM_controller(
input CLOCK,_reset, start,
input [15:0] IN,
output reg [15:0] OR,
output reg done
);
reg [15:0] IR,OUT; //输入,输出寄存器
reg [63:0] LFSR = 64'h3170604015ABCDEF; //十六位总密钥
reg [18:0] X; //分密钥X
reg [21:0] Y; //分密钥Y
reg [22:0] Z; //分密钥Z
reg M; //使能总位
reg code; //每次得到的1位密码流
reg [3:0] count; //4位计数器
//----------计数器-----------
always@(posedge CLOCK or posedge _reset) //为15即已加密16位
begin
if(_reset==1)
count<=0;
else if(current_state==init)
count<=0;
else if(current_state==encrypt)
count<=count+1;
end
reg current_state, next_state;
//----------状态定义----------
localparam init=1'b0; //初始态
localparam encrypt=1'b1; //加密态
/*---------输出逻辑----------
输出发生器定义了数据通路,并且通过行为描述来定义了数据通路的控制信号*/
always@(posedge CLOCK or posedge _reset)
begin
if(_reset==1)
OR <= 0;
else
begin
case(current_state)
init:
begin //初始化
if(start==1)
begin
IR <= IN;
X <= LFSR[18:0];
Y <= LFSR[40:19];
Z <= LFSR[63:41];
end
end
encrypt:begin
OR <= {OR[14:0],code^IR[15]};
IR <= {IR[14:0],IR[15]};
X <= {X[17:0],X[13]^X[16]^X[17]^X[18]};
Y <= {Y[20:0],Y[20]^Y[21]};
Z <= {Z[21:0],Z[7]^Z[20]^Z[21]^Z[22]};
end
endcase
end
end
always@(Z)
begin
M = X[8]&Y[10]|Y[10]&Z[10]|X[8]&Z[10];
code = ((~M|~X[8])&X[18])^((~M|~Y[10])&Y[21])^((~M|~Z[10])&Z[22]);
end
//----------状态转换----------
always@(*)
begin
case(current_state)
init:
begin
if(start==1)
begin
done=0;
next_state=encrypt;
end
else
begin
done=0;
next_state=init;
end
end
encrypt:
begin
if(count<4'hF)
begin
done=0;
next_state=encrypt;
end
else
begin
done=1;
next_state=init;
OUT=OR;
end
end
endcase
end
//----------状态转换----------
always@(posedge CLOCK or posedge _reset)
begin
if(_reset==1)
current_state <= init;
else
current_state <= next_state;
end
endmodule
完整的工程文件我已经上传到CSDN了,可以去我的主页查看并下载完整的工程文件进行使用
工程内包含文件如下图:
WeLab虚拟面板设置图片:
输入待处理16位二进制数,按下start按键启动,即可得到处理后的四位十六进制数据
注意:对称式加密即输入待加密数据能得到加密好的密文,输入得到的密文启动就会解密得到原来的明文,对于时序电路软件接收数据可能会存在延时,导致显示结果不是最终处理完的结果,对于输入的数据可以多按几次启动键来确保获得稳定的输出结果。若不能正常工作,其问题还是出在时钟周期的设置上,将JuLabPocket_TOP.v文件中调用clock_devider的参数RATIO调大或调小来选取适当的时钟周期,从而使得电路能正常工作
详细课程设计报告地址:https://wenku.baidu.com/view/5acf011d24c52cc58bd63186bceb19e8b9f6ec76