SM3_core/rtl/sm3_cmprss_core.v
2020-08-04 23:11:26 +08:00

385 lines
12 KiB
Verilog
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`timescale 1ns / 1ps
`include "sm3_cfg.v"
//////////////////////////////////////////////////////////////////////////////////
// Author: ljgibbs / lf_gibbs@163.com
// Create Date: 2020/07/27
// Design Name: sm3
// Module Name: sm3_cmprss_core
// Description:
// SM3 迭代压缩模块-SM3 迭代压缩核心单元
// 输入位宽INPT_DW1 定义支持32/64bit
// 输出位宽:与输入位宽对应
// 特性:在 64bit 位宽下,采用二度展开结构(暂未)
// Dependencies:
// inc/sm3_cfg.v
// Revision:
// Revision 0.01 - File Created
//////////////////////////////////////////////////////////////////////////////////
module sm3_cmprss_core (
input clk,
input rst_n,
input [`INPT_DW1:0] expnd_inpt_wj_i,
input [`INPT_DW1:0] expnd_inpt_wjj_i,
input expnd_inpt_lst_i,
input expnd_inpt_vld_i,
output [255:0] cmprss_otpt_res_o,
output cmprss_otpt_vld_o
);
//每时钟输入的数据字数量 32bit位宽1 64bit位宽2
`ifdef SM3_INPT_DW_32
localparam [1:0] INPT_WORD_NUM = 2'd1;
`elsif SM3_INPT_DW_64
localparam [1:0] INPT_WORD_NUM = 2'd2;
`endif
localparam [6:0] CMPRSS_RND_NUM = 7'd64;
//A-H 字寄存器
reg [31 : 0] reg_a;
reg [31 : 0] reg_b;
reg [31 : 0] reg_c;
reg [31 : 0] reg_d;
reg [31 : 0] reg_e;
reg [31 : 0] reg_f;
reg [31 : 0] reg_g;
reg [31 : 0] reg_h;
reg [31 : 0] reg_tj;
reg [5 : 0] reg_cmprss_round;
reg cmprss_round_sm_16;
//结果寄存器
reg sm3_res_valid;
reg sm3_res_valid_r1;
reg [255:0] sm3_res;
reg cmprss_blk_res_finish;
//A-H 字运算中间值
wire [31 : 0] reg_a_new;
wire [31 : 0] reg_b_new;
wire [31 : 0] reg_c_new;
wire [31 : 0] reg_d_new;
wire [31 : 0] reg_e_new;
wire [31 : 0] reg_f_new;
wire [31 : 0] reg_g_new;
wire [31 : 0] reg_h_new;
`ifdef SM3_INPT_DW_64
wire [31 : 0] reg_a_mid;
wire [31 : 0] reg_b_mid;
wire [31 : 0] reg_c_mid;
wire [31 : 0] reg_d_mid;
wire [31 : 0] reg_e_mid;
wire [31 : 0] reg_f_mid;
wire [31 : 0] reg_g_mid;
wire [31 : 0] reg_h_mid;
//两轮运算的 tj 值
wire [31 : 0] reg_tj_rnd_odd;
wire [31 : 0] reg_tj_rnd_even;
`endif
//块迭代标志
wire cmprss_new_round_valid;
wire cmprss_blk_start;
wire cmprss_blk_finish;
//对输入的 wj 值打拍或者分离
reg sm3_wj_wjj_vld_r;
reg sm3_wj_wjj_lst_r;
`ifdef SM3_INPT_DW_32
reg [31:0] wj_rnd_r;
reg [31:0] wjj_rnd_r;
`elsif SM3_INPT_DW_64
reg [31:0] wj_rnd_odd_r;
reg [31:0] wjj_rnd_odd_r;
reg [31:0] wj_rnd_even_r;
reg [31:0] wjj_rnd_even_r;
`endif
//输入每数据块所属数据字计数
reg [5:0] inpt_wrd_of_blk_cntr;
wire inpt_wrd_of_blk_cntr_add;
wire inpt_wrd_of_blk_cntr_clr;
//管理tj寄存器
always @(posedge clk or negedge rst_n) begin
if(~rst_n |cmprss_blk_res_finish) begin
reg_tj <= 32'h79cc4519;
end
else if(sm3_wj_wjj_vld_r)begin
if(reg_cmprss_round == 6'd16 - INPT_WORD_NUM)
reg_tj <= 32'h9d8a7a87;
else begin
`ifdef SM3_INPT_DW_32
reg_tj <= {reg_tj[30:0],reg_tj[31]};
`elsif SM3_INPT_DW_64 //每次循环左移两位
reg_tj <= {reg_tj[29:0],reg_tj[31:30]};
`endif
end
end
end
`ifdef SM3_INPT_DW_64
//两轮运算的 tj 值
assign reg_tj_rnd_odd = {reg_tj[30:0],reg_tj[31]};
assign reg_tj_rnd_even = reg_tj;
`endif
//对输入的 wj 值打拍或者分离
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
sm3_wj_wjj_vld_r <= 1'b0;
sm3_wj_wjj_lst_r <= 1'b0;
end
else begin
sm3_wj_wjj_vld_r <= expnd_inpt_vld_i;
sm3_wj_wjj_lst_r <= expnd_inpt_lst_i;
end
end
`ifdef SM3_INPT_DW_32
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
wj_rnd_r <= 32'd0;
wjj_rnd_r <= 32'd0;
end
else begin
wj_rnd_r <= expnd_inpt_wj_i;
wjj_rnd_r <= expnd_inpt_wjj_i;
end
end
`elsif SM3_INPT_DW_64
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
wj_rnd_odd_r <= 32'd0;
wjj_rnd_odd_r <= 32'd0;
wj_rnd_even_r <= 32'd0;
wjj_rnd_even_r <= 32'd0;
end
else begin
{wj_rnd_even_r,wj_rnd_odd_r} <= expnd_inpt_wj_i;
{wjj_rnd_even_r,wjj_rnd_odd_r} <= expnd_inpt_wjj_i;
end
end
`endif
//标记最后一块
assign cmprss_new_round_valid = sm3_wj_wjj_vld_r;
assign cmprss_blk_finish = inpt_wrd_of_blk_cntr_clr;
//块运算完成信号
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
cmprss_blk_res_finish <= 1'b0;
end
else begin
cmprss_blk_res_finish <= inpt_wrd_of_blk_cntr_clr;
end
end
//输入每数据块所属数据字计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
inpt_wrd_of_blk_cntr <= 6'b0;
end else if(inpt_wrd_of_blk_cntr_add)begin
inpt_wrd_of_blk_cntr <= inpt_wrd_of_blk_cntr + INPT_WORD_NUM;
end else if(inpt_wrd_of_blk_cntr_clr)begin
inpt_wrd_of_blk_cntr <= 6'b0;
end
end
assign inpt_wrd_of_blk_cntr_add = sm3_wj_wjj_vld_r;
assign inpt_wrd_of_blk_cntr_clr = sm3_wj_wjj_vld_r
&& inpt_wrd_of_blk_cntr == (CMPRSS_RND_NUM - INPT_WORD_NUM);
//压缩迭代轮计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
reg_cmprss_round <= 6'd0;
end
else if(cmprss_blk_finish)begin
reg_cmprss_round <= 6'd0;
end
else if(cmprss_new_round_valid)begin
reg_cmprss_round <= reg_cmprss_round + INPT_WORD_NUM;
end
end
//产生16轮内标记
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
cmprss_round_sm_16 <= 1'b0;
end else begin
cmprss_round_sm_16 <= reg_cmprss_round < 6'd16 - INPT_WORD_NUM; //标识当前小于
end
end
//寄存器组初值装填与迭代
always @(posedge clk or negedge rst_n) begin
if((~rst_n) || sm3_res_valid_r1) begin
reg_a <= 32'h7380166f;//0;
reg_b <= 32'h4914b2b9;//0;
reg_c <= 32'h172442d7;//0;
reg_d <= 32'hda8a0600;//0;
reg_e <= 32'ha96f30bc;//0;
reg_f <= 32'h163138aa;//0;
reg_g <= 32'he38dee4d;//0;
reg_h <= 32'hb0fb0e4e;//0;
end
else if(cmprss_new_round_valid)begin
reg_a <= reg_a_new;
reg_b <= reg_b_new;
reg_c <= reg_c_new;
reg_d <= reg_d_new;
reg_e <= reg_e_new;
reg_f <= reg_f_new;
reg_g <= reg_g_new;
reg_h <= reg_h_new;
end
else if(cmprss_blk_res_finish)begin
reg_a <= reg_a ^ sm3_res[255-:32];
reg_b <= reg_b ^ sm3_res[223-:32];
reg_c <= reg_c ^ sm3_res[191-:32];
reg_d <= reg_d ^ sm3_res[159-:32];
reg_e <= reg_e ^ sm3_res[127-:32];
reg_f <= reg_f ^ sm3_res[95 -:32];
reg_g <= reg_g ^ sm3_res[63 -:32];
reg_h <= reg_h ^ sm3_res[31 -:32];
end
end
//消息所属块均计算完毕,输出计算结果
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
sm3_res_valid <= 1'b0;
sm3_res_valid_r1 <= 1'b0;
end
else begin
sm3_res_valid <= sm3_wj_wjj_lst_r;
sm3_res_valid_r1 <= sm3_res_valid;
end
end
always @(posedge clk or negedge rst_n) begin
if((~rst_n) || sm3_res_valid_r1) begin
sm3_res <= {32'h7380166f, 32'h4914b2b9, 32'h172442d7, 32'hda8a0600, 32'ha96f30bc, 32'h163138aa, 32'he38dee4d, 32'hb0fb0e4e};
end
else if(cmprss_blk_res_finish)begin
sm3_res <= {reg_a,reg_b,reg_c,reg_d,reg_e,reg_f,reg_g,reg_h} ^ sm3_res;
end
end
`ifdef SM3_INPT_DW_32
sm3_cmprss_ceil_comb U_sm3_cmprss_ceil_comb
(
.cmprss_round_sm_16_i (cmprss_round_sm_16),
.tj_i (reg_tj),
.reg_a_i (reg_a),
.reg_b_i (reg_b),
.reg_c_i (reg_c),
.reg_d_i (reg_d),
.reg_e_i (reg_e),
.reg_f_i (reg_f),
.reg_g_i (reg_g),
.reg_h_i (reg_h),
.wj_i (wj_rnd_r),
.wjj_i (wjj_rnd_r),
.reg_a_o (reg_a_new),
.reg_b_o (reg_b_new),
.reg_c_o (reg_c_new),
.reg_d_o (reg_d_new),
.reg_e_o (reg_e_new),
.reg_f_o (reg_f_new),
.reg_g_o (reg_g_new),
.reg_h_o (reg_h_new)
);
`elsif SM3_INPT_DW_64
sm3_cmprss_ceil_comb U_sm3_cmprss_ceil_comb
(
.cmprss_round_sm_16_i (cmprss_round_sm_16),
.tj_i (reg_tj_rnd_even),
.reg_a_i (reg_a),
.reg_b_i (reg_b),
.reg_c_i (reg_c),
.reg_d_i (reg_d),
.reg_e_i (reg_e),
.reg_f_i (reg_f),
.reg_g_i (reg_g),
.reg_h_i (reg_h),
.wj_i (wj_rnd_even_r),
.wjj_i (wjj_rnd_even_r),
.reg_a_o (reg_a_mid),
.reg_b_o (reg_b_mid),
.reg_c_o (reg_c_mid),
.reg_d_o (reg_d_mid),
.reg_e_o (reg_e_mid),
.reg_f_o (reg_f_mid),
.reg_g_o (reg_g_mid),
.reg_h_o (reg_h_mid)
);
sm3_cmprss_ceil_comb U_sm3_cmprss_ceil_comb_1
(
.cmprss_round_sm_16_i (cmprss_round_sm_16),
.tj_i (reg_tj_rnd_odd),
.reg_a_i (reg_a_mid),
.reg_b_i (reg_b_mid),
.reg_c_i (reg_c_mid),
.reg_d_i (reg_d_mid),
.reg_e_i (reg_e_mid),
.reg_f_i (reg_f_mid),
.reg_g_i (reg_g_mid),
.reg_h_i (reg_h_mid),
.wj_i (wj_rnd_odd_r),
.wjj_i (wjj_rnd_odd_r),
.reg_a_o (reg_a_new),
.reg_b_o (reg_b_new),
.reg_c_o (reg_c_new),
.reg_d_o (reg_d_new),
.reg_e_o (reg_e_new),
.reg_f_o (reg_f_new),
.reg_g_o (reg_g_new),
.reg_h_o (reg_h_new)
);
`endif
//输出控制
assign cmprss_otpt_vld_o = sm3_res_valid_r1;
assign cmprss_otpt_res_o = sm3_res;
`ifdef SM3_CMPRS_SIM_DBG
`ifdef SM3_CMPRS_SIM_FILE_LOG
integer file;
initial begin:inital_file
file = $fopen("wj.txt","w");
end
`endif
generate
if(1) begin
always@(*) begin
if(cmprss_otpt_vld_o)
begin
`ifdef SM3_CMPRS_SIM_FILE_LOG
$fdisplay(file,"LOG: res : %64h",cmprss_otpt_res_o);
`else
$display("LOG: res : %64h",cmprss_otpt_res_o);
`endif
end
end
end
endgenerate
`endif
endmodule