如何将Nexys A7上AES算法输出映射到十六进制数码管显示
Nexys A7开发板AES输出接数码管显示实现方案
实现步骤
- 第一步:提取AES输出的目标4字节
你编写的AES模块输出state_out为128bit位宽,定义为[0:127],因此:- 取前4字节:直接截取
state_out[0:31],共32bit对应8位十六进制数,刚好适配Nexys A7的8个板载数码管 - 取后4字节:截取
state_out[96:127]即可
- 取前4字节:直接截取
- 第二步:实现七段数码管译码模块
把4bit二进制数转换为数码管段选信号,Nexys A7的数码管为共阳型,低电平点亮对应段,参考代码如下:
module hex7seg( input [3:0] din, output reg [6:0] seg ); always @(*) begin case(din) 4'h0: seg = 7'b1000000; 4'h1: seg = 7'b1111001; 4'h2: seg = 7'b0100100; 4'h3: seg = 7'b0110000; 4'h4: seg = 7'b0011001; 4'h5: seg = 7'b0010010; 4'h6: seg = 7'b0000010; 4'h7: seg = 7'b1111000; 4'h8: seg = 7'b0000000; 4'h9: seg = 7'b0010000; 4'ha: seg = 7'b0001000; 4'hb: seg = 7'b0000011; 4'hc: seg = 7'b1000110; 4'hd: seg = 7'b0100001; 4'he: seg = 7'b0000110; 4'hf: seg = 7'b0001110; default: seg = 7'b1111111; endcase end endmodule
- 第三步:实现数码管动态扫描模块
Nexys A7的数码管为动态扫描结构,需要用开发板的100MHz系统时钟产生扫描时序,避免显示闪烁,参考代码如下:
module seg_scan( input clk, input rst_n, input [31:0] disp_data, // 输入的32位待显示数据,对应8位十六进制 output reg [7:0] an, // 数码管位选,低电平点亮 output [6:0] seg // 段选输出 ); reg [16:0] scan_cnt; // 计数分频产生1kHz左右的扫描频率 reg [3:0] curr_din; reg [2:0] scan_sel; // 分频计数 always @(posedge clk or negedge rst_n) begin if(!rst_n) scan_cnt <= 0; else scan_cnt <= scan_cnt + 1'b1; end always @(posedge clk or negedge rst_n) begin if(!rst_n) scan_sel <= 0; else if(scan_cnt == 17'h1ffff) scan_sel <= scan_sel + 1'b1; end // 位选信号生成 always @(*) begin case(scan_sel) 3'd0: an = 8'b11111110; 3'd1: an = 8'b11111101; 3'd2: an = 8'b11111011; 3'd3: an = 8'b11110111; 3'd4: an = 8'b11101111; 3'd5: an = 8'b11011111; 3'd6: an = 8'b10111111; 3'd7: an = 8'b01111111; default: an = 8'b11111111; endcase end // 对应位的4bit数据选择 always @(*) begin case(scan_sel) 3'd0: curr_din = disp_data[3:0]; 3'd1: curr_din = disp_data[7:4]; 3'd2: curr_din = disp_data[11:8]; 3'd3: curr_din = disp_data[15:12]; 3'd4: curr_din = disp_data[19:16]; 3'd5: curr_din = disp_data[23:20]; 3'd6: curr_din = disp_data[27:24]; 3'd7: curr_din = disp_data[31:28]; default: curr_din = 4'h0; endcase end // 实例化译码模块 hex7seg u_hex7seg( .din(curr_din), .seg(seg) ); endmodule
- 第四步:顶层模块整合
把AES模块、扫描模块整合,也可以额外加按键控制切换显示前4字节还是后4字节,参考顶层代码如下:
module aes_top( input clk, input rst_n, input disp_sel, // 按键控制,0显示前4字节,1显示后4字节 output [7:0] an, output [6:0] seg ); // 测试用的明文和密钥,可根据需求改为接拨码开关输入 wire [127:0] state_in = 128'h00_11_22_33_44_55_66_77_88_99_aa_bb_cc_dd_ee_ff; wire [127:0] key_in = 128'h00_01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f; wire [127:0] state_out; wire [127:0] key_out; reg [31:0] disp_data; // 实例化AES模块 AES u_aes( .key_out(key_out), .state_out(state_out), .key_in(key_in), .state_in(state_in) ); // 选择显示的4字节 always @(*) begin if(disp_sel) disp_data = state_out[96:127]; // 后4字节 else disp_data = state_out[0:31]; // 前4字节 end // 实例化扫描模块 seg_scan u_seg_scan( .clk(clk), .rst_n(rst_n), .disp_data(disp_data), .an(an), .seg(seg) ); endmodule
- 第五步:绑定引脚
根据Nexys A7的官方约束文件,把clk、rst_n、disp_sel、an、seg对应到实际板载引脚,综合下载后即可看到显示结果。
补充说明
你当前的测试bench存在小问题:$finish放在赋值语句之后没有延迟,仿真时AES的组合逻辑还没输出就结束了,修改方式是在$finish之前加延迟,比如改成#50 $finish;就能看到正确的仿真输出。
内容的提问来源于stack exchange,提问作者Roger B
相关产品推荐
相关产品推荐

