-
Notifications
You must be signed in to change notification settings - Fork 0
/
scytale_decryption.v
120 lines (87 loc) · 2.5 KB
/
scytale_decryption.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
`timescale 1ns / 1ps
`define RESET 0
`define WAIT_DATA 10
`define DECRYPT 20
module scytale_decryption#(
parameter D_WIDTH = 8,
parameter KEY_WIDTH = 8,
parameter MAX_NOF_CHARS = 50,
parameter START_DECRYPTION_TOKEN = 8'hFA
)(
// Clock and reset interface
input clk,
input rst_n,
// Input interface
input[D_WIDTH - 1:0] data_i,
input valid_i,
// Decryption Key
input[KEY_WIDTH - 1 : 0] key_N,
input[KEY_WIDTH - 1 : 0] key_M,
// Output interface
output reg[D_WIDTH - 1:0] data_o,
output reg valid_o,
output reg busy
);
reg[MAX_NOF_CHARS * D_WIDTH - 1: 0] regData;
reg[D_WIDTH - 1 : 0] data_i_reg;
reg[7 : 0] state, nextState, index, row_select,
column_select, nextRow_select, nextColumn_select, nextIndex;
reg valid_i_reg, next_valid_o;
always @(posedge clk) begin
data_i_reg <= data_i;
valid_i_reg <= valid_i;
valid_o <= next_valid_o;
state <= nextState;
column_select<= nextColumn_select;
row_select<= nextRow_select;
index <= nextIndex;
if(~rst_n)
state <= `RESET;
end
always @(*) begin
case(state)
`RESET: begin
next_valid_o = 0;
data_o = 0;
busy = 0;
nextState = `WAIT_DATA;
nextColumn_select = 0;
nextRow_select = 0;
nextIndex = 0;
end
`WAIT_DATA: begin
busy = 0;
// Stocare date ce vin pe intrare
if(valid_i_reg && data_i_reg != START_DECRYPTION_TOKEN) begin
regData[8*index +: 8] = data_i_reg;
nextIndex = index + 1;
end
// Tratare sfarsit introducere date
else if(data_i_reg == START_DECRYPTION_TOKEN) begin
nextState = `DECRYPT;
busy = 1;
next_valid_o = 1;
end
end
`DECRYPT: begin
// Selectare element de pus pe iesire
data_o = regData[D_WIDTH * (key_N * column_select + row_select) +: D_WIDTH];
// Avans pe coloana urmatoare
nextColumn_select = column_select+ 1;
if (nextColumn_select == key_M) begin
// Trecem pe urmatoarea "linie"
nextColumn_select = 0;
nextRow_select = row_select+ 1;
end
nextIndex = index - 1;
// Daca am terminat, revenim in starea de asteptare a datelor
if (nextIndex == 0) begin
nextState = `WAIT_DATA;
nextColumn_select = 0;
nextRow_select = 0;
next_valid_o = 0;
end
end
endcase
end
endmodule