SM3_core/rtl/sm3_expnd_core.v

424 lines
20 KiB
Coq
Raw Normal View History

`timescale 1ns / 1ps
`include "sm3_cfg.v"
//////////////////////////////////////////////////////////////////////////////////
// Author: ljgibbs / lf_gibbs@163.com
// Create Date: 2020/07/26
// Design Name: sm3
// Module Name: sm3_expnd_core
// Description:
// SM3 扩展模块-SM3 扩展核心单元
// 输入位宽INPT_DW1 定义支持32/64bit
// 输出位宽与输入位宽对应
// 特性预载寄存器68->65clk(32b)/66->65clk(64b),目前仅支持32bit默认开启
// Dependencies:
// inc/sm3_cfg.v
// Revision:
// Revision 0.01 - File Created
//////////////////////////////////////////////////////////////////////////////////
module sm3_expnd_core (
input clk,
input rst_n,
input [`INPT_DW1:0] pad_inpt_d_i,
input pad_inpt_vld_i,
input pad_inpt_lst_i,
output pad_inpt_rdy_o,
output [`INPT_DW1:0] expnd_otpt_wj_o,
output [`INPT_DW1:0] expnd_otpt_wjj_o,
output expnd_otpt_lst_o,
output expnd_otpt_vld_o
);
2020-07-26 23:18:12 +08:00
//每时钟输入的数据字数量 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 WORD_INPT_NUM = 512 / 32;//16
localparam [5:0] WORD_EXPND_ROUND = 52;//(68 - 16)
`ifdef SM3_EXPND_PRE_LOAD_REG
localparam PRE_BUFF_N = 4;
`endif
//字扩展电路
wire [31:0] word_wj_expand;
2020-07-26 23:18:12 +08:00
wire [31:0] word_wjj_otpt;
wire [31:0] word_wj_expand_tmp_1;
wire [31:0] word_wj_expand_tmp_2;
2020-07-26 23:18:12 +08:00
//字扩展电路64bit
`ifdef SM3_INPT_DW_64
wire [31:0] word_wj_expand_w1;
wire [31:0] word_wjj_otpt_w1;
wire [31:0] word_wj_expand_tmp_1_w1;
wire [31:0] word_wj_expand_tmp_2_w1;
`endif
wire word_exp_push_reg_ena; //字拓展并压入寄存器组使能
//寄存器组 reg
reg [31:0] word_buff [15:0]; //16字缓冲区 缓存16个32位字
wire word_buff_shft_ena;
2020-07-26 23:18:12 +08:00
wire[31:0] word_buff_new_push; //寄存器组新入组变量
//64bit 新增的一个扩展字
`ifdef SM3_INPT_DW_64
wire[31:0] word_buff_new_push_w1;
`endif
2020-07-26 23:18:12 +08:00
//预缓冲区
`ifdef SM3_EXPND_PRE_LOAD_REG
reg [31:0] word_buff_nb_pre [3:0];//4字 下一字预缓存区
wire word_buff_rpd_shft_ena;
wire word_buff_nb_pre_shft_ena;
`endif
//预缓冲区数据数量计数
`ifdef SM3_EXPND_PRE_LOAD_REG
reg [1:0] word_buff_nb_pre_cntr;
wire word_buff_nb_pre_cntr_add;
wire word_buff_nb_pre_cntr_clr;
`endif
//原始字输入计数
reg [3:0] msg_blk_word_inpt_cntr;
wire msg_blk_word_inpt_cntr_add;
wire msg_blk_word_inpt_cntr_clr;
//字扩展输出计数指本数据块中扩展电路的扩展字输出数量
reg [5:0] msg_blk_word_exp_cntr;
wire msg_blk_word_exp_cntr_add;
wire msg_blk_word_exp_cntr_clr;
//消息扩展主状态机
`define STT_W 8
`define STT_W1 `STT_W - 1
reg [`STT_W1:0] state;
reg [`STT_W1:0] nxt_state;
localparam IDLE = `STT_W'h1;
localparam INPT_ORGN_5W = `STT_W'h2;//输入5个原始字w0-w4到寄存器组中
localparam INPT_OTPT = `STT_W'h4;//输入剩下的11个原始字w5-w15并输出11对扩展字
localparam EXP_OTPT = `STT_W'h8;//扩展并输出扩展字,直至扩展得到第48个扩展字w63
localparam EXP_OTPT_PRE_INPT = `STT_W'h10;//当w64生成后开始预接收下一消息块前3个消息字 wn0-wn2消息字写入预存储寄存器
localparam EXP_OTPT_FIN = `STT_W'h20;//扩展以及输出结束输出最后一对扩展字,接收下一消息块的第4个消息字 wn3,判断预存储器中数据数量
localparam WAT_PRE_INPT_FIN = `STT_W'h40;//若预存储器数据数量>0 <4,等待预寄存器存储完成 4
localparam RPD_SHFT = `STT_W'h80;//快速移位原始数据,128b位宽的形式包括预存储寄存器
//SM3填充消息输入反压逻辑
2020-07-26 23:18:12 +08:00
wire pad_inpt_d_inpt_rdy;
//消息最后一块标记信号
reg msg_lst_blk_flg;
wire msg_lst_blk_flg_ena;
wire msg_lst_blk_flg_clr;
//SM3填充消息输入反压逻辑仅在 EXP_OTPT 状态下仅进行扩展不提供输入
2020-07-26 23:18:12 +08:00
assign pad_inpt_d_inpt_rdy = ( state == IDLE
|| state == INPT_ORGN_5W
|| (state == INPT_OTPT && ~(nxt_state == EXP_OTPT))//提前一个周期置低输入有效信号
|| state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
|| state == WAT_PRE_INPT_FIN
|| state == RPD_SHFT
) ;
//原始字输入计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
msg_blk_word_inpt_cntr <= 4'b0;
end else if(msg_blk_word_inpt_cntr_add)begin
2020-07-26 23:18:12 +08:00
msg_blk_word_inpt_cntr <= msg_blk_word_inpt_cntr + INPT_WORD_NUM;
end else if(msg_blk_word_inpt_cntr_clr)begin
msg_blk_word_inpt_cntr <= 4'b0;
end
end
2020-07-26 23:18:12 +08:00
assign msg_blk_word_inpt_cntr_add = pad_inpt_vld_i; //计数输入消息字
assign msg_blk_word_inpt_cntr_clr = 1'b0; //0-f 对应 16 个消息字计数自清
//字扩展输出计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
msg_blk_word_exp_cntr <= 6'b0;
end else if(msg_blk_word_exp_cntr_clr)begin
msg_blk_word_exp_cntr <= 6'b0;
end else if(msg_blk_word_exp_cntr_add)begin
2020-07-26 23:18:12 +08:00
msg_blk_word_exp_cntr <= msg_blk_word_exp_cntr + INPT_WORD_NUM;
end
end
assign msg_blk_word_exp_cntr_add = word_exp_push_reg_ena;//字扩展并移入寄存器使能
2020-07-26 23:18:12 +08:00
assign msg_blk_word_exp_cntr_clr = msg_blk_word_exp_cntr == WORD_EXPND_ROUND;//完成所有扩展次数后清除计数器
`ifdef SM3_EXPND_PRE_LOAD_REG
//预缓冲区数据数量计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
word_buff_nb_pre_cntr <= 2'b0;
end else if(word_buff_nb_pre_cntr_add)begin
word_buff_nb_pre_cntr <= word_buff_nb_pre_cntr + INPT_WORD_NUM;
end else if(word_buff_nb_pre_cntr_clr)begin
word_buff_nb_pre_cntr <= 2'b0;
end
end
2020-07-26 23:18:12 +08:00
assign word_buff_nb_pre_cntr_add = ( state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
|| state == WAT_PRE_INPT_FIN
) && pad_inpt_vld_i;//预输入状态下的外部数据输入有效
assign word_buff_nb_pre_cntr_clr = state == RPD_SHFT ;//预输入寄存器该状态下被移出
`endif
//消息最后一块标记信号
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
msg_lst_blk_flg <= 1'b0;
end else if(msg_lst_blk_flg_ena)begin
msg_lst_blk_flg <= 1'b1;
end else if(msg_lst_blk_flg_clr)begin
msg_lst_blk_flg <= 1'b0;
end
end
2020-07-26 23:18:12 +08:00
assign msg_lst_blk_flg_ena = pad_inpt_lst_i;
assign msg_lst_blk_flg_clr = expnd_otpt_lst_o;
//消息扩展主状态机
always @(*) begin
case (state)
IDLE: begin
2020-07-26 23:18:12 +08:00
if(pad_inpt_vld_i)
nxt_state = INPT_ORGN_5W;
else
nxt_state = IDLE;
end
INPT_ORGN_5W:begin
2020-07-26 23:18:12 +08:00
if(msg_blk_word_inpt_cntr == 4'd4 && pad_inpt_vld_i)
nxt_state = INPT_OTPT;//输入前 5 个原始字后开始一边输入一边输出
else
nxt_state = INPT_ORGN_5W;
end
INPT_OTPT:begin
2020-07-26 23:18:12 +08:00
if(msg_blk_word_inpt_cntr == (WORD_INPT_NUM - INPT_WORD_NUM) && pad_inpt_vld_i)
nxt_state = EXP_OTPT;//输入所有 16 个原始字后开始向寄存器组输入扩展字
else
nxt_state = INPT_OTPT;
end
EXP_OTPT:begin
if(msg_blk_word_exp_cntr == 6'd48)
nxt_state = EXP_OTPT_PRE_INPT; //在生成w63第48个扩展字后允许下一个块预输入
else
nxt_state = EXP_OTPT;
end
EXP_OTPT_PRE_INPT:begin
2020-07-26 23:18:12 +08:00
if(msg_blk_word_exp_cntr == (WORD_EXPND_ROUND - INPT_WORD_NUM))
nxt_state = EXP_OTPT_FIN; //在生成51个扩展字后,转入最后一个扩展字
else
nxt_state = EXP_OTPT_PRE_INPT;
end
EXP_OTPT_FIN:begin
2020-07-26 23:18:12 +08:00
`ifdef SM3_EXPND_PRE_LOAD_REG
if(word_buff_nb_pre_cntr == 2'd0 && ~pad_inpt_vld_i)
nxt_state = IDLE; //扩展期间无预缓存字转为idle等待下次输入
else if((word_buff_nb_pre_cntr == 3'd4 - INPT_WORD_NUM) && pad_inpt_vld_i)
nxt_state = RPD_SHFT;//4 个预缓存字转入 RPD_SHFT
else
nxt_state = WAT_PRE_INPT_FIN;//存在预缓存字转入 WAT_PRE_INPT_FIN等待条件满足
`else
nxt_state = IDLE;
`endif
end
WAT_PRE_INPT_FIN:begin
2020-07-26 23:18:12 +08:00
`ifdef SM3_EXPND_PRE_LOAD_REG
if((word_buff_nb_pre_cntr == 3'd4 - INPT_WORD_NUM) && pad_inpt_vld_i)
nxt_state = RPD_SHFT; //4 个预缓存字转入 RPD_SHFT
else
nxt_state = WAT_PRE_INPT_FIN;//存在预缓存字转入WAT_PRE_INPT_FIN
`else
nxt_state = IDLE;
`endif
end
RPD_SHFT:begin
2020-07-26 23:18:12 +08:00
`ifdef SM3_EXPND_PRE_LOAD_REG
if(pad_inpt_vld_i)
nxt_state = INPT_OTPT; //5个原始字输入完毕开始一边输入一边输出
else
nxt_state = RPD_SHFT;//等待第5个原始字
`else
nxt_state = IDLE;
`endif
end
default:
nxt_state = IDLE;
endcase
end
always @(posedge clk or negedge rst_n) begin
if(~rst_n)
state <= `STT_W'b1;
else begin
state <= nxt_state;
end
end
//扩展电路
assign word_wj_expand_tmp_1 = word_buff[0] ^ word_buff[7] ^ {word_buff[13][16:0],word_buff[13][31:17]};
assign word_wj_expand_tmp_2 = {word_wj_expand_tmp_1 ^ {word_wj_expand_tmp_1[16:0],word_wj_expand_tmp_1[31:17]}
^ {word_wj_expand_tmp_1[8:0],word_wj_expand_tmp_1[31:9]}};
assign word_wj_expand = word_wj_expand_tmp_2 ^ word_buff[10] ^ {word_buff[3][24:0],word_buff[3][31:25]};
2020-07-26 23:18:12 +08:00
`ifdef SM3_INPT_DW_64
assign word_wj_expand_tmp_1_w1 = word_buff[1] ^ word_buff[8] ^ {word_buff[14][16:0],word_buff[14][31:17]};
assign word_wj_expand_tmp_2_w1 = {word_wj_expand_tmp_1_w1 ^ {word_wj_expand_tmp_1_w1[16:0],word_wj_expand_tmp_1_w1[31:17]}
^ {word_wj_expand_tmp_1_w1[8:0],word_wj_expand_tmp_1_w1[31:9]}};
assign word_wj_expand_w1 = word_wj_expand_tmp_2 ^ word_buff[11] ^ {word_buff[4][24:0],word_buff[4][31:25]};
`endif
`ifdef SM3_INPT_DW_32
assign word_wjj_otpt = word_buff[11] ^ word_buff[15];
`elsif SM3_INPT_DW_64
assign word_wjj_otpt = word_buff[10] ^ word_buff[14];
assign word_wjj_otpt_w1 = word_buff[11] ^ word_buff[15];
`endif
//扩展电路输出至主寄存器使能
assign word_exp_push_reg_ena = (state == EXP_OTPT
|| state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
);
// 根据当前扩展轮数确定补充进缓冲区的数据类型原始数据(0-15) 扩展数据(16-67) 0( >67)
assign word_buff_new_push = (state == IDLE
|| state == INPT_ORGN_5W
|| state == RPD_SHFT
|| state == INPT_OTPT
2020-07-26 23:18:12 +08:00
`ifdef SM3_INPT_DW_32
) ? pad_inpt_d_i[31:0] :
`elsif SM3_INPT_DW_64
) ? pad_inpt_d_i[63:32] :
`endif
word_exp_push_reg_ena ? word_wj_expand :
32'd0;
2020-07-26 23:18:12 +08:00
`ifdef SM3_INPT_DW_64
assign word_buff_new_push_w1 = (state == IDLE
|| state == INPT_ORGN_5W
|| state == RPD_SHFT
|| state == INPT_OTPT
) ? pad_inpt_d_i[31:0] :
word_exp_push_reg_ena ? word_wj_expand_w1 :
32'd0;
`endif
//消息缓冲区 push
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin : buff_init
integer i;
2020-07-26 23:18:12 +08:00
for ( i = 0 ; i < WORD_INPT_NUM; i = i + 1) begin:buff_init
word_buff[i] <= 32'd0;
end
end
else if(word_buff_shft_ena)begin : buff_shift // w0 <- w1; w1 <- w2;....w15 <- w_new
integer i;
2020-07-26 23:18:12 +08:00
`ifdef SM3_INPT_DW_32
for ( i = WORD_INPT_NUM - 1 ; i > 0 ; i = i - 1) begin
word_buff[i-1] <= word_buff[i];
end
word_buff[15] <= word_buff_new_push;
`elsif SM3_INPT_DW_64
for ( i = (WORD_INPT_NUM / INPT_WORD_NUM)- 1 ; i > 0 ; i = i - 1) begin
word_buff[2*i-1] <= word_buff[2*i+1];
word_buff[2*(i-1)] <= word_buff[2*i];
end
{word_buff[14],word_buff[15]} <= {word_buff_new_push,word_buff_new_push_w1};
`endif
end
2020-07-26 23:18:12 +08:00
`ifdef SM3_EXPND_PRE_LOAD_REG
else if(word_buff_rpd_shft_ena)begin : buff_rpd_shift //快速移位阶段
word_buff[15] <= pad_inpt_d_i;
word_buff[14] <= word_buff_nb_pre[3];
word_buff[13] <= word_buff_nb_pre[2];
word_buff[12] <= word_buff_nb_pre[1];
word_buff[11] <= word_buff_nb_pre[0];
end
`endif
end
2020-07-26 23:18:12 +08:00
assign word_buff_shft_ena = (state == IDLE && pad_inpt_vld_i)
|| (state == INPT_ORGN_5W && pad_inpt_vld_i)
|| (state == INPT_OTPT && pad_inpt_vld_i)
|| state == EXP_OTPT
|| state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
;//寄存器组左移使能 20.5.13 fix
2020-07-26 23:18:12 +08:00
`ifdef SM3_EXPND_PRE_LOAD_REG
assign word_buff_rpd_shft_ena = state == RPD_SHFT && pad_inpt_vld_i; //缓存区快速移位使能
//消息预缓冲区
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin : pre_buff_init
integer i;
for ( i = 0 ; i < PRE_BUFF_N; i = i + 1) begin : pre_buff_init
word_buff_nb_pre[i] <= 32'd0;
end
end
2020-07-26 23:18:12 +08:00
else if(word_buff_nb_pre_shft_ena)begin : pre_buff_shift // wnb0 <- wnb1....wnb3 <- input
integer i;
for ( i = PRE_BUFF_N - 1 ; i > 0 ; i = i - 1) begin
word_buff_nb_pre[i-1] <= word_buff_nb_pre[i];
end
word_buff_nb_pre[PRE_BUFF_N - 1] <= pad_inpt_d_i;
end
end
2020-07-26 23:18:12 +08:00
assign word_buff_nb_pre_shft_ena = ( state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
|| state == WAT_PRE_INPT_FIN
) && pad_inpt_vld_i;//预缓冲区移位使能
`endif
//输出控制
2020-07-26 23:18:12 +08:00
`ifdef SM3_INPT_DW_32
assign expnd_otpt_wj_o = word_buff[11];// 从倒数第5个寄存器输出
assign expnd_otpt_wjj_o = word_wjj_otpt;
`elsif SM3_INPT_DW_64
assign expnd_otpt_wj_o = {word_buff[10],word_buff[11]};
assign expnd_otpt_wjj_o = {word_wjj_otpt,word_wjj_otpt_w1};
`endif
assign expnd_otpt_vld_o = (state == INPT_OTPT && pad_inpt_vld_i) //20.5.13 fix
|| state == EXP_OTPT
|| state == EXP_OTPT_PRE_INPT
|| state == EXP_OTPT_FIN
;
2020-07-26 23:18:12 +08:00
assign expnd_otpt_lst_o = msg_lst_blk_flg && state == EXP_OTPT_FIN;
assign pad_inpt_rdy_o = pad_inpt_d_inpt_rdy; //反压控制
2020-07-26 23:18:12 +08:00
//调试打印信息 debug log
`ifdef SM3_EXPND_SIM_DBG
generate
2020-07-27 11:36:28 +08:00
always@(posedge clk) begin
if(expnd_otpt_vld_o)begin
`ifdef SM3_INPT_DW_32
$display("LOG: EXPND WORD %32h | %32h", expnd_otpt_wj_o[31:0],expnd_otpt_wjj_o[31:0],);
`elsif SM3_INPT_DW_64
$display("LOG: EXPND WORD %32h | %32h | %32h | %32h" ,expnd_otpt_wj_o[63:32]
,expnd_otpt_wj_o[31:0]
,expnd_otpt_wjj_o[63:32]
,expnd_otpt_wjj_o[31:0]
);
`endif
end
end
endgenerate
`endif
endmodule