⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms4_control_ori.v

📁 用Verilog实现国内第一个商用密码算法SMS4的加密和解密。
💻 V
字号:
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on

module sms4_control_ori (
                         busy,
                         dout_vld,
                         key_str,
                         get_data,
                         get_key,
                         counter,
                         mode,
                         //ed_mode,
                         exp_run,
                         ed_run,
                         start,
                         enc,
                         din_vld,
                         key_vld,
                         clk,
                         reset);
                         
parameter DWIDTH=128;
parameter IDLE=4'b0000;
parameter GETKEY1=4'b0001;
parameter GETKEY2=4'b0010;
parameter KEYEXP=4'b0011;
parameter WAITDATA=4'b0100;
parameter GETDATASK1=4'b0101;
parameter GETDATASK2=4'b0110;
parameter ROUND1A=4'b0111;
parameter ROUND1B=4'b1000;
parameter ROUND2A=4'b1010;
parameter FINISH1=4'b1011;
parameter WAITNEXT=4'b1100;
parameter WAIT_CLK=4'b1101;
parameter FINISH2=4'b1110;

output dout_vld,busy,key_str,get_data,mode,exp_run,ed_run;
output  get_key;
output [0:4] counter;

input clk,reset,start,enc,din_vld;
input[0:1] key_vld;

reg [0:4] counter;
reg get_key;
reg dout_vld,busy,key_str,get_data,mode,exp_run,ed_run;
reg [0:3] current_control,next_control;

always @(posedge clk or negedge reset)
if(!reset)
   counter<=0;
else case(enc)
       1'b1 : 
          if(counter==5'b11111)
            counter<=0;
              else if(exp_run==1)
                counter<=counter+1;
       1'b0 :
           if(exp_run==1&&ed_run==0&&counter!=5'b11111)
             counter<=counter+1;
              else if(exp_run==1&&ed_run==0&&counter==5'b11111)
               counter<=5'b11111;
                else if(exp_run==1&&ed_run==1)
                 counter<=counter-1;
       endcase

always @(posedge clk or negedge reset)
if(!reset)
   current_control<=0;
else
   current_control<=next_control;
   
always @ (current_control or start or enc or din_vld or key_vld or counter)
  case(current_control)
       IDLE: if(start==1&&key_vld==2'b01)
              next_control=GETKEY1;
               else if(start==1&&key_vld==2'b10&&enc==0)
                next_control=GETKEY2;
                 else 
                  next_control=IDLE;
    GETKEY1: if(start==0)
              next_control=IDLE;
               else if(key_vld!=2'b01&&enc==0)
                next_control=KEYEXP;
                 else if(key_vld!=2'b01&&din_vld!=1&&enc==1)
                  next_control=WAITDATA;
                   else if(key_vld!=2'b01&&din_vld==1&&enc==1)
                    next_control=GETDATASK1;
                     else
                      next_control=GETKEY1;
    GETKEY2: if(start==0)
              next_control=IDLE;
               else if(key_vld!=2'b10&&din_vld!=1)
                next_control=WAITDATA;
                 else if(key_vld!=2'b10&&din_vld==1)
                  next_control=GETDATASK2;
                   else
                    next_control=GETKEY2;
   WAITDATA: if(start==0)
              next_control=IDLE;
               else if(din_vld==1&&enc==1)
                next_control=GETDATASK1;
                 else if(din_vld==1&&enc==0)
                   next_control=GETDATASK2;
                   else
                    next_control=WAITDATA;
     KEYEXP: if(start==0)
              next_control=IDLE;
               else if(counter==5'b11111&&din_vld!=1)
                next_control=WAITDATA;
                 else if(counter==5'b11111&&din_vld==1)
                  next_control=GETDATASK2;
                   else 
                    next_control=KEYEXP;
  GETDATASK1: if(start==0)
              next_control=IDLE;
               else if(din_vld!=1)
                next_control=ROUND1A;                
                   else
                    next_control=GETDATASK1;
   GETDATASK2: if(start==0)
              next_control=IDLE;              
                 else 
                 next_control=WAIT_CLK;
   WAIT_CLK: if(start==0)
               next_control=IDLE;
                else
                  next_control=ROUND2A;
                //if(din_vld!=1)
                 // next_control=ROUND2A;
                 // else
                 //   next_control=GETDATASK2;
    ROUND1A: next_control=ROUND1B;
    ROUND1B: if(start==0)
              next_control=IDLE;
               else if(counter==5'b11111)
                next_control=FINISH1;
                 else
                  next_control=ROUND1B;
    ROUND2A: if(start==0)
              next_control=IDLE;
               else if(counter==5'b0)
                next_control=FINISH2;
                 else
                  next_control=ROUND2A;
     FINISH1: if(start==0)
              next_control=IDLE;
               else 
                next_control=WAITNEXT;
     FINISH2: if(start==0)
              next_control=IDLE;
               else 
                next_control=WAITNEXT;
   WAITNEXT: if(start==0)
              next_control=IDLE;
               else if(key_vld==2'b01)
                next_control=GETKEY1;
                 //else if(enc==0&&key_vld==2'b10)
                 // next_control=GETKEY2;
                   else
                    next_control=WAITNEXT;
    default: next_control=IDLE;
  endcase
  
always @ (current_control)
  case(current_control)     
     IDLE: begin
           dout_vld=0;
           busy=0;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
           //ed_mode=0;
           end
  GETKEY1: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=1;
           get_data=0;
           mode=1;
           exp_run=0;
           ed_run=0;
          // ed_mode=0;
           end
  GETKEY2: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
           //ed_mode=0;
           end
   KEYEXP: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=1;
           exp_run=1;
           ed_run=0;
          // ed_mode=0;
           end
 WAITDATA: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
          // ed_mode=0;
           end
GETDATASK1: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=1;
           mode=1;
           exp_run=0;
           ed_run=0;
         //  ed_mode=0;
           end
GETDATASK2: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=1;
           mode=0;
           exp_run=0;
           ed_run=0;
         //  ed_mode=1;
           end
WAIT_CLK: begin
          dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=1;
           ed_run=1;
          // ed_mode=1;
           end
  ROUND1A: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=1;
           exp_run=1;
           ed_run=0;
         //  ed_mode=0;
           end 
  ROUND1B: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=1;
           exp_run=1;
           ed_run=1;
         //  ed_mode=1;
           end
  ROUND2A: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=1;
           ed_run=1;
        //   ed_mode=1;
           end
  FINISH1: begin
           dout_vld=1;
           busy=1;
           key_str=1;
           get_key=0;
           get_data=0;
           mode=1;
           exp_run=0;
           ed_run=1;
         //  ed_mode=0;
           end
  FINISH2: begin
           dout_vld=1;
           busy=1;
           key_str=1;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
         //  ed_mode=0;
           end
 WAITNEXT: begin
           dout_vld=0;
           busy=1;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
         //  ed_mode=0;
           end
  default: begin
           dout_vld=0;
           busy=0;
           key_str=0;
           get_key=0;
           get_data=0;
           mode=0;
           exp_run=0;
           ed_run=0;
          // ed_mode=0;
           end
  endcase
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -