| 1 |
/**********************************************************-*-verilog-*- |
| 2 |
* |
| 3 |
* CRYPT(3) |
| 4 |
* 2段x2/25パイプライン, latency=800 |
| 5 |
* |
| 6 |
* $Id$ |
| 7 |
* |
| 8 |
*/ |
| 9 |
|
| 10 |
module crypt22(rst, |
| 11 |
clk, clk5, st_gate, |
| 12 |
ien, i_salt, i_k, |
| 13 |
bsy, |
| 14 |
oen, o_k, o_h); |
| 15 |
|
| 16 |
// システム制御 |
| 17 |
input rst; // 回路リセット |
| 18 |
input clk; // 32MHz 前後 |
| 19 |
input clk5; // 5倍速clk |
| 20 |
input st_gate; // 5倍速のgate基準信号 |
| 21 |
|
| 22 |
// 入力(いくつかのビットは無視される) |
| 23 |
input ien; // データがそろったときにageる |
| 24 |
input [11:0] i_salt; // そのまま下位モジュールへ |
| 25 |
input [55:0] i_k; // 一部はそのまま下位モジュールへ |
| 26 |
|
| 27 |
// 状態 |
| 28 |
output bsy; // 内部でループ回ってるとき立つ |
| 29 |
|
| 30 |
// 出力 |
| 31 |
output oen; // あがってる時 |
| 32 |
output [55:0] o_k; // キー(俺順) |
| 33 |
output [1:64] o_h; // 出力 |
| 34 |
|
| 35 |
// KR 回すのに有効な空間 |
| 36 |
parameter krmsk = 28'b0000_0000_1111_1111_111_111_111_111; |
| 37 |
parameter klmsk = 28'b000_000_000_000_000_000_000_000_0000; |
| 38 |
|
| 39 |
`include "conf.v" |
| 40 |
`include "func_des.v" |
| 41 |
|
| 42 |
// for pipeline |
| 43 |
reg [27:0] kr; |
| 44 |
wire [27:0] mkr, kri; |
| 45 |
wire kr_end; // 鍵が一周しそうになったら立つ |
| 46 |
assign mkr = kr | ~krmsk; |
| 47 |
assign {kr_end, kri} = mkr + 28'b1; |
| 48 |
|
| 49 |
wire [1:32] l0, l1, l01, l10; |
| 50 |
wire [1:32] r0, r1, r01, r10; |
| 51 |
wire [55:0] k0, k1, k01, k10; |
| 52 |
|
| 53 |
// phase cache |
| 54 |
reg [27:0] kp0, kp1; |
| 55 |
|
| 56 |
/* |
| 57 |
* ステート |
| 58 |
* bit11 が立っているときは、KLセットアップ |
| 59 |
*/ |
| 60 |
reg bsy; |
| 61 |
reg [11:0] st; |
| 62 |
wire [11:0] sti; |
| 63 |
wire sti_of; |
| 64 |
assign {sti_of, sti} = st + 12'b1; |
| 65 |
|
| 66 |
// 近い将来、sbram を復活させることがあるかもしれない |
| 67 |
parameter KL_START = 12'b1_000000_0_0000; |
| 68 |
|
| 69 |
// ステート |
| 70 |
parameter KL_FINISH_WAIT = 12'b1_000000_0_0000; |
| 71 |
parameter KL_IDLE = 12'b1_111111_1_1110; |
| 72 |
parameter KL_SETUP = 12'b1_111111_1_1111; |
| 73 |
|
| 74 |
/* |
| 75 |
* ゲートにアクセスするために用いる |
| 76 |
* registered にしないと、大いなる遅延ペナルティを喰う |
| 77 |
*/ |
| 78 |
reg gate_filla, gate_fillb; |
| 79 |
reg gate_fetcha, gate_fetchb; |
| 80 |
|
| 81 |
// 内部レジスタ(もはや不要??) |
| 82 |
reg [27:0] kl; |
| 83 |
|
| 84 |
/* |
| 85 |
* ステートのループ |
| 86 |
*/ |
| 87 |
always @(posedge clk or posedge rst) |
| 88 |
if (rst) |
| 89 |
begin |
| 90 |
bsy <= 0; |
| 91 |
st <= KL_IDLE; |
| 92 |
kl <= 28'b0; |
| 93 |
kr <= 28'b0; |
| 94 |
kp0 <= 28'b0; |
| 95 |
kp1 <= 28'b0; |
| 96 |
end |
| 97 |
else |
| 98 |
begin |
| 99 |
/* |
| 100 |
* fill/fetch のステート |
| 101 |
* kr をインクリメントし続ける |
| 102 |
*/ |
| 103 |
if (gate_filla || gate_fillb) |
| 104 |
begin |
| 105 |
kr <= kri; |
| 106 |
|
| 107 |
// phase cache のアップデート |
| 108 |
if (&kr[kbn - 1:0]) |
| 109 |
begin |
| 110 |
if (kr[kbn]) |
| 111 |
kp0 <= kri; // kr + 28'b100_0000_0000; |
| 112 |
else |
| 113 |
kp1 <= kri; // kr + 28'b100_0000_0000; |
| 114 |
end |
| 115 |
end |
| 116 |
|
| 117 |
// ステート |
| 118 |
if (st == KL_SETUP) |
| 119 |
begin |
| 120 |
// 1ウェイト入ってしまうが、gate セットアップのために必要 |
| 121 |
bsy <= 1; |
| 122 |
st <= sti; |
| 123 |
end |
| 124 |
else if (st < 512) |
| 125 |
begin |
| 126 |
/* |
| 127 |
* fill/fetch のステート |
| 128 |
*/ |
| 129 |
if (kr_end && (gate_filla || gate_fillb)) |
| 130 |
begin |
| 131 |
st <= st + (1888 - 224 + 1); // fetchのみステート |
| 132 |
end |
| 133 |
else if (st == 383) |
| 134 |
st <= 64; |
| 135 |
else |
| 136 |
st <= sti; |
| 137 |
end |
| 138 |
else if (st < 2048) |
| 139 |
begin |
| 140 |
// fetch のみのステート |
| 141 |
if (sti == 2048) |
| 142 |
begin |
| 143 |
// RAM のセットアップに入る |
| 144 |
st <= KL_FINISH_WAIT; |
| 145 |
bsy <= 0; |
| 146 |
//kl <= i_pc1_l(rolk(pc1_l(kl + 1), 4'hF)); |
| 147 |
end |
| 148 |
|
| 149 |
st <= sti; |
| 150 |
end |
| 151 |
else if (st == KL_FINISH_WAIT) |
| 152 |
begin |
| 153 |
// 処理を終えたので、 |
| 154 |
// ホストが ien を下げるのを待つ |
| 155 |
// このとき、bsy はおちているはず |
| 156 |
if (!ien) |
| 157 |
st <= KL_IDLE; |
| 158 |
end |
| 159 |
else // KL_IDLE を処理するつもりになっている |
| 160 |
begin |
| 161 |
if (ien) |
| 162 |
begin |
| 163 |
st <= KL_SETUP; // XXX これだとgate 開かないんじゃ?? |
| 164 |
kr <= i_k[55:28] & ~krmsk; |
| 165 |
bsy <= 1; |
| 166 |
end |
| 167 |
end |
| 168 |
end |
| 169 |
|
| 170 |
/* |
| 171 |
* ゲート制御 |
| 172 |
* 本来はステートに対してゲートが決まるのだが |
| 173 |
* タイミング的に間に合わないので、 |
| 174 |
* pre-increment した sti で、ゲートの開閉を決める |
| 175 |
*/ |
| 176 |
always @(posedge clk or posedge rst) |
| 177 |
if (rst) |
| 178 |
begin |
| 179 |
gate_filla <= 0; |
| 180 |
gate_fillb <= 0; |
| 181 |
gate_fetcha <= 0; |
| 182 |
gate_fetchb <= 0; |
| 183 |
end |
| 184 |
else |
| 185 |
begin |
| 186 |
gate_filla <= (sti < 64 |
| 187 |
|| (320 <= sti && sti < 384)); |
| 188 |
gate_fillb <= (160 <= sti && sti < 224); |
| 189 |
|
| 190 |
// 現状では、必ず fillb-fetchb ですべてが終わる |
| 191 |
gate_fetcha <= (160 <= sti && sti < 224); |
| 192 |
gate_fetchb <= ((320 <= sti && sti < 384) |
| 193 |
|| (1888 <= sti && sti < 2048)); |
| 194 |
end |
| 195 |
|
| 196 |
/* |
| 197 |
* pipline gate - fill |
| 198 |
* 5ステージ毎に新規のキーを押し込んでいく |
| 199 |
*/ |
| 200 |
parameter kmsk = {krmsk, klmsk}; |
| 201 |
assign {l0, r0, k0} = (gate_filla && st_gate |
| 202 |
? {64'b0, kmux(kmsk, i_k, {kr, 28'b0})} |
| 203 |
: {l10, r10, kmux(kmsk, i_k, k10)}); |
| 204 |
assign {l1, r1, k1} = (gate_fillb && st_gate |
| 205 |
? {64'b0, kmux(kmsk, i_k, {kr, 28'b0})} |
| 206 |
: {l01, r01, kmux(kmsk, i_k, k01)}); |
| 207 |
|
| 208 |
/* |
| 209 |
* pipelines thru=1 lat=800(clk5), 160(clk) |
| 210 |
* これを25段並べられるデヴァイスは、神! |
| 211 |
*/ |
| 212 |
(* ALTERA_ATTRIBUTE = "AUTO_PACKED_REGISTERS_STRATIX=NORMAL;STRATIX_OPTIMIZATION_TECHNIQUE=SPEED" *) |
| 213 |
des_pipeline #(kmsk) des1(clk5, l0, r0, i_k, k0, l01, r01, k01, i_salt, {kp1, kp0}, clk, 1'b0, 11'b0, 16'b0); |
| 214 |
(* ALTERA_ATTRIBUTE = "AUTO_PACKED_REGISTERS_STRATIX=NORMAL;STRATIX_OPTIMIZATION_TECHNIQUE=SPEED" *) |
| 215 |
des_pipeline #(kmsk) des2(clk5, l1, r1, i_k, k1, l10, r10, k10, i_salt, {kp1, kp0}, clk, 1'b0, 11'b0, 16'b0); |
| 216 |
|
| 217 |
// パイプラインの出力を取り込む |
| 218 |
assign oen = (gate_fetcha || gate_fetchb); |
| 219 |
assign o_k = kmux(kmsk, i_k, gate_fetcha ? k01 : k10); |
| 220 |
assign o_h = fp(gate_fetcha ? {l01, r01} : {l10, r10}); |
| 221 |
|
| 222 |
endmodule // crypt22 |
| 223 |
|
| 224 |
/* |
| 225 |
* Local variables: |
| 226 |
* tab-width: 4 |
| 227 |
* End: |
| 228 |
*/ |