From 6a873d8a412770b30fc0bf14a23cdf2a12bbb840 Mon Sep 17 00:00:00 2001 From: fan Li <15201710458@163.com> Date: Tue, 21 Jul 2020 21:12:29 +0800 Subject: [PATCH] RTL code and check finish --- rtl/inc/sm3_cfg.v | 48 +++++++ rtl/sm3_pad_core.v | 303 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100644 rtl/inc/sm3_cfg.v create mode 100644 rtl/sm3_pad_core.v diff --git a/rtl/inc/sm3_cfg.v b/rtl/inc/sm3_cfg.v new file mode 100644 index 0000000..c4880ed --- /dev/null +++ b/rtl/inc/sm3_cfg.v @@ -0,0 +1,48 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Author: ljgibbs / lf_gibbs@163.com +// Create Date: 2020/07/19 +// Design Name: sm3 +// Module Name: sm3_cfg +// Description: +// SM3 模块配置信息 +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +////////////////////////////////////////////////////////////////////////////////// +//定义设计阶段 +`define DESIGN_SIM +// `define DESIGN_SYNT + +//定义 SM3 输入位宽 +// `define SM3_INPT_DW_32 +`define SM3_INPT_DW_64 + +`ifdef SM3_INPT_DW_32 + `define INPT_DW 32 +`elsif SM3_INPT_DW_64 + `define INPT_DW 64 +`endif + +`define INPT_DW1 (INPT_DW - 1) +`define INPT_BYTE_DW1 (INPT_DW/8 - 1) +`define INPT_BYTE_DW (INPT_BYTE_DW1 + 1) + +//定义 SM3 输出位宽 +// `define SM3_OTPT_DW_32 +`define SM3_OTPT_DW_64 +// `define SM3_OTPT_DW_128 +// `define SM3_OTPT_DW_256 + +`ifdef SM3_OTPT_DW_32 + `define OTPT_DW 32 +`elsif SM3_OTPT_DW_64 + `define OTPT_DW 64 +`elsif SM3_OTPT_DW_128 + `define OTPT_DW 128 +`elsif SM3_OTPT_DW_256 + `define OTPT_DW 256 +`endif + +`define OTPT_DW1 (OTPT_DW - 1) \ No newline at end of file diff --git a/rtl/sm3_pad_core.v b/rtl/sm3_pad_core.v new file mode 100644 index 0000000..eaed294 --- /dev/null +++ b/rtl/sm3_pad_core.v @@ -0,0 +1,303 @@ +`timescale 1ns / 1ps +`include "./inc/sm3_cfg" +////////////////////////////////////////////////////////////////////////////////// +// Author: ljgibbs / lf_gibbs@163.com +// Create Date: 2020/07/19 +// Design Name: sm3 +// Module Name: sm3_pad_core +// Description: +// SM3 填充模块-SM3 填充核心单元 +// 输入位宽:INPT_DW1 定义 +// 输出位宽:与输入位宽一致 +// Dependencies: +// inc/sm3_cfg.v +// Revision: +// Revision 0.01 - File Created +////////////////////////////////////////////////////////////////////////////////// +module sm3_pad_core ( + input clk, + input rst_n, + + input [`INPT_DW1:0] msg_inpt_d_i, + input [`INPT_BYTE_DW1:0] msg_inpt_vld_byte_i, + input msg_inpt_vld_i, + input msg_inpt_lst_i, + + input pad_otpt_ena_i, + + output msg_inpt_rdy_o, + + output [`INPT_DW1:0] pad_otpt_d_o, + output pad_otpt_lst_o, + output pad_otpt_vld_o +); + +localparam [15:0] PAD_BLK_WD_NUM = 16; +localparam [15:0] PAD_BLK_BIT_LEN_WD_NUM = 2; +localparam [15:0] PAD_BLK_WD_NUM_INIT = PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM; +localparam [ 3:0] PAD_BLK_WD_NUM_WTHT_LEN = PAD_BLK_WD_NUM - PAD_BLK_BIT_LEN_WD_NUM; + +//每时钟输入的数据字数量 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 + +//最后一个数据的填充图样 +`ifdef SM3_INPT_DW_32 + reg [31:0] lst_data_pad_mask; +`elsif SM3_INPT_DW_64 + reg [63:0] lst_data_pad_mask; +`endif + +//对输入数据打拍 beat inpt signals +reg [`INPT_DW1:0] msg_inpt_d_r1; +reg [`INPT_BYTE_DW1:0] msg_inpt_vld_byte_r1; +reg msg_inpt_vld_r1; +reg msg_inpt_lst_r1; + +//输入字数统计 count inpt words(32bit) +reg [15:0] inpt_wd_cntr; +wire inpt_wd_cntr_add; +wire inpt_wd_cntr_clr; + +//填充字数统计 count padded words +reg [4:0] pad_00_wd_cntr; +wire pad_00_wd_cntr_inpt_updt; //随数据输入递减 dec with data inpt +wire pad_00_wd_cntr_pad_updt; //随数据填充递减 dec with pad data +wire pad_00_wd_cntr_rld; //对于新消息,装填计数器 reload cntr for new msg + +//输入比特长度 count inpt bit length +wire [63:0] inpt_bit_cntr; + +//填充后数据输出使能 +wire pad_otpt_ena; + +//标记填充需要在数据块基础上新增块 flag: new pad block need add on original msg +reg add_new_blk_flg; +wire add_new_blk_flg_ena; +wire add_new_blk_flg_clr; + +//统计最后一个数据的有效字节数 cnt vld byte of the last inpt data +wire [3:0] inpt_vld_byte_cnt; +wire inpt_vld_byte_cmplt; + +//流程状态机 +`define STT_W 9 +`define STT_W1 `STT_W - 1 + +reg [`STT_W1:0] state; +reg [`STT_W1:0] nxt_state; + +localparam IDLE = `STT_W'h1; +localparam INPT_DATA = `STT_W'h2; +localparam INPT_PAD_LST_DATA = `STT_W'h4; +localparam PAD_10_DATA = `STT_W'h8; +localparam PAD_00_DATA = `STT_W'h10; +localparam PAD_LEN_H = `STT_W'h20; +localparam PAD_LEN_L = `STT_W'h40; +localparam ADD_BLK_PAD_00 = `STT_W'h80; +localparam PAD_00_WAT_NEW_BLK = `STT_W'h100; + +//对输入数据打拍 beat inpt signals +always @(posedge clk or negedge rst_n) begin + if(~rst_n) begin + msg_inpt_d_r1 <= INPT_DW'b0; + msg_inpt_vld_byte_r1 <= INPT_BYTE_DW'b0; + msg_inpt_vld_r1 <= 1'b0; + msg_inpt_lst_r1 <= 1'b0; + end else begin + msg_inpt_d_r1 <= msg_inpt_d_i; + msg_inpt_vld_byte_r1 <= msg_inpt_vld_byte_i; + msg_inpt_vld_r1 <= msg_inpt_vld_i; + msg_inpt_lst_r1 <= msg_inpt_lst_i; + end +end + +//生成最后一个数据的填充图样 +always @(*) begin + `ifdef SM3_INPT_DW_32 + case (inpt_vld_byte_cnt) + 4'd0: lst_data_pad_mask = 32'd8000_0000; + 4'd1: lst_data_pad_mask = 32'h0080_0000; + 4'd2: lst_data_pad_mask = 32'h0000_8000; + 4'd3: lst_data_pad_mask = 32'h0000_0080; + 4'd4: lst_data_pad_mask = 32'h0000_0000; + default: lst_data_pad_mask = 32'd8000_0000; + endcase + `elsif SM3_INPT_DW_64 + case (inpt_vld_byte_cnt) + 4'd0: lst_data_pad_mask = 64'd8000_0000_0000_0000; + 4'd1: lst_data_pad_mask = 64'h0080_0000_0000_0000; + 4'd2: lst_data_pad_mask = 64'h0000_8000_0000_0000; + 4'd3: lst_data_pad_mask = 64'h0000_0080_0000_0000; + 4'd4: lst_data_pad_mask = 64'd0000_0000_8000_0000; + 4'd5: lst_data_pad_mask = 64'h0000_0000_0080_0000; + 4'd6: lst_data_pad_mask = 64'h0000_0000_0000_8000; + 4'd7: lst_data_pad_mask = 64'h0000_0000_0000_0080; + 4'd8: lst_data_pad_mask = 64'h0000_0000_0000_0000; + default: lst_data_pad_mask = 64'd8000_0000_0000_0000; + endcase + `endif +end + + +//统计最后一个数据的有效字节数 +always @(*) begin + inpt_vld_byte_cnt = 4'b0; + for(i = 0;i <= `INPT_BYTE_DW1;i=i+1) begin + inpt_vld_byte_cnt = inpt_vld_byte_cnt + msg_inpt_vld_byte_r1[i]; + end +end + +assign inpt_vld_byte_cmplt = inpt_vld_byte_cnt == 4 * INPT_WORD_NUM; + +//输入字数统计 +always @(posedge clk or negedge rst_n) begin + if(~rst_n) begin + inpt_wd_cntr <= 16'b0; + end else if(inpt_wd_cntr_add)begin + inpt_wd_cntr <= inpt_wd_cntr + INPT_WORD_NUM; + end else if(inpt_wd_cntr_clr)begin + inpt_wd_cntr <= 16'b0; + end +end +assign inpt_wd_cntr_add = msg_inpt_vld_r1; +assign inpt_wd_cntr_clr = pad_otpt_lst_o; +assign inpt_bit_cntr = {43'd0,inpt_wd_cntr,5'd0}; + +//填充字数统计 +always @(posedge clk or negedge rst_n) begin + if(~rst_n) begin + pad_00_wd_cntr <= PAD_BLK_WD_NUM_INIT;//16-2=14 + end else if(pad_00_wd_cntr_inpt_updt)begin + pad_00_wd_cntr <= pad_00_wd_cntr == INPT_WORD_NUM + ? PAD_BLK_WD_NUM + : pad_00_wd_cntr - INPT_WORD_NUM; + end else if(pad_00_wd_cntr_rld)begin + pad_00_wd_cntr <= PAD_BLK_WD_NUM_INIT; + end else if(pad_00_wd_cntr_pad_updt)begin + pad_00_wd_cntr <= pad_00_wd_cntr - INPT_WORD_NUM; + end +end +assign pad_00_wd_cntr_inpt_updt = msg_inpt_vld_r1; +assign pad_00_wd_cntr_pad_updt = state == PAD_00_DATA || state == ADD_BLK_PAD_00; +assign pad_00_wd_cntr_rld = pad_otpt_lst_o; + + + +//标记填充需要在数据块基础上新增块 +always @(posedge clk or negedge rst_n) begin + if(~rst_n) begin + add_new_blk_flg <= 'b0; + end else if(add_new_blk_flg_ena)begin + add_new_blk_flg <= 1'b1; + end else if(add_new_blk_flg_clr)begin + add_new_blk_flg <= 'b0; + end +end +//置起信号 last信号输入时,输入数据为 14 + 16 * N word +assign add_new_blk_flg_ena = msg_inpt_lst_i && inpt_wd_cntr[3:0] == (5'h10 - INPT_WORD_NUM); +assign add_new_blk_flg_clr = state == ADD_BLK_PAD_00; + +//实现流程状态机 +always @(*) begin + case (state) + IDLE: begin + if(msg_inpt_vld_i) + nxt_state = INPT_DATA; + else + nxt_state = IDLE; + end + INPT_DATA: begin //直接输出输入数据,无需填充 + if(msg_inpt_lst_i) + nxt_state = INPT_PAD_LST_DATA; + else + nxt_state = INPT_DATA; + end + INPT_PAD_LST_DATA: begin//根据最后一个输入数据的情况,确定填充策略 + if(inpt_vld_byte_cmplt) + nxt_state = PAD_10_DATA; + else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM)//14 - 1/2 + nxt_state = PAD_LEN_H; + else if(inpt_wd_cntr[3:0] < PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM) + nxt_state = PAD_00_DATA; + else if(inpt_wd_cntr[3:0] > PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM) + nxt_state = ADD_BLK_PAD_00; + end + PAD_10_DATA: begin//填充由1个1和若干个0组成的数据 + if(add_new_blk_flg) + nxt_state = ADD_BLK_PAD_00; + else if(inpt_wd_cntr[3:0] == PAD_BLK_WD_NUM_WTHT_LEN - INPT_WORD_NUM - 1'b1) + nxt_state = PAD_LEN_H; + else + nxt_state = PAD_00_DATA; + end + ADD_BLK_PAD_00:begin//为新增的填充块填0 + if(pad_00_wd_cntr == INPT_WORD_NUM) //32位时填充2个周期,64位时填充1个周期 + nxt_state = PAD_00_WAT_NEW_BLK; + else + nxt_state = ADD_BLK_PAD_00; + end + PAD_00_WAT_NEW_BLK: + if(~pad_otpt_ena_i) //等待上一块处理完毕后 开始新的一块输出 + nxt_state = PAD_00_WAT_NEW_BLK; + else + nxt_state = PAD_00_DATA; + PAD_00_DATA: //填充全 0 数据 + if(pad_00_wd_cntr == INPT_WORD_NUM) + nxt_state = PAD_LEN_H; + else + nxt_state = PAD_00_DATA; + PAD_LEN_H: //填充比特长度的高32位/填充整个比特长度 + `ifdef SM3_INPT_DW_32 + nxt_state = PAD_LEN_L; + `elsif SM3_INPT_DW_64 + nxt_state = IDLE; + `endif + PAD_LEN_L: + nxt_state = IDLE; + 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 pad_otpt_ena = state == PAD_10_DATA + || state == PAD_00_DATA + || state == PAD_LEN_H + || state == PAD_LEN_L + || state == ADD_BLK_PAD_00 ; +//输出控制 +`ifdef SM3_INPT_DW_32 + assign pad_otpt_d_o = state == PAD_10_DATA ? 32'h8000_0000: + state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask: + state == PAD_00_DATA || state == ADD_BLK_PAD_00? 32'h0: + state == PAD_LEN_H ? inpt_bit_cntr[63-:32]: + state == PAD_LEN_L ? inpt_bit_cntr[31-:32]: + msg_inpt_d_r1; + assign pad_otpt_lst_o = state == PAD_LEN_L; +`elsif SM3_INPT_DW_64 + assign pad_otpt_d_o = state == PAD_10_DATA ? 64'h8000_0000_0000_0000: + state == INPT_PAD_LST_DATA? msg_inpt_d_r1 | lst_data_pad_mask: + state == PAD_00_DATA || state == ADD_BLK_PAD_00? 64'h0: + state == PAD_LEN_H ? inpt_bit_cntr: + msg_inpt_d_r1; + assign pad_otpt_lst_o = state == PAD_LEN_H; +`endif + +assign pad_otpt_vld_o = msg_inpt_vld_r1 || pad_otpt_ena; +assign msg_inpt_rdy_o = pad_otpt_ena_i && (state == IDLE || state == INPT_DATA); + + +endmodule \ No newline at end of file