summaryrefslogtreecommitdiff
path: root/streebog_wrapper.v
blob: a2ef47ddddfeacc679812dab74a3fce965f2d9cb (plain) (blame)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
module streebog_wrapper
	(
		input		wire           clk,
		input		wire           rst,

		input		wire           cs,
		input		wire           we,

		input		wire  [ 7: 0]	address,
		input		wire  [31: 0]	write_data,
		output	wire	[31: 0]	read_data
	);

	  //----------------------------------------------------------------
	  // Internal constant and parameter definitions.
	  //----------------------------------------------------------------
	localparam ADDR_NAME0		= 8'h00;
	localparam ADDR_NAME1		= 8'h01;
	localparam ADDR_VERSION		= 8'h02;

	localparam ADDR_CTRL			= 8'h08;		// {short, final, update, init}
	localparam ADDR_STATUS		= 8'h09;		// {valid, ready}
	localparam ADDR_BLOCK_BITS	= 8'h0a;		// block length in bits
	localparam ADDR_MODE			= 8'h0b;		// 0=long (512-bit) mode, 1=short (256-bit) mode

	localparam ADDR_BLOCK0		= 8'h10;
	localparam ADDR_BLOCK1		= 8'h11;
	localparam ADDR_BLOCK2		= 8'h12;
	localparam ADDR_BLOCK3		= 8'h13;
	localparam ADDR_BLOCK4		= 8'h14;
	localparam ADDR_BLOCK5		= 8'h15;
	localparam ADDR_BLOCK6		= 8'h16;
	localparam ADDR_BLOCK7		= 8'h17;
	localparam ADDR_BLOCK8		= 8'h18;
	localparam ADDR_BLOCK9		= 8'h19;
	localparam ADDR_BLOCK10		= 8'h1a;
	localparam ADDR_BLOCK11		= 8'h1b;
	localparam ADDR_BLOCK12		= 8'h1c;
	localparam ADDR_BLOCK13		= 8'h1d;
	localparam ADDR_BLOCK14		= 8'h1e;
	localparam ADDR_BLOCK15		= 8'h1f;

	localparam ADDR_DIGEST0		= 8'h20;
	localparam ADDR_DIGEST1		= 8'h21;
	localparam ADDR_DIGEST2		= 8'h22;
	localparam ADDR_DIGEST3		= 8'h23;
	localparam ADDR_DIGEST4		= 8'h24;
	localparam ADDR_DIGEST5		= 8'h25;
	localparam ADDR_DIGEST6		= 8'h26;
	localparam ADDR_DIGEST7		= 8'h27;
	localparam ADDR_DIGEST8		= 8'h28;
	localparam ADDR_DIGEST9		= 8'h29;
	localparam ADDR_DIGEST10	= 8'h2a;
	localparam ADDR_DIGEST11	= 8'h2b;
	localparam ADDR_DIGEST12	= 8'h2c;
	localparam ADDR_DIGEST13	= 8'h2d;
	localparam ADDR_DIGEST14	= 8'h2e;
	localparam ADDR_DIGEST15	= 8'h2f;


	localparam CTRL_INIT_BIT		= 0;
	localparam CTRL_UPDATE_BIT		= 1;
	localparam CTRL_FINAL_BIT		= 2;

	localparam STATUS_READY_BIT	= 0;
	localparam STATUS_VALID_BIT	= 1;

	localparam CORE_NAME0     = 32'h73747265;	// "stre"
	localparam CORE_NAME1     = 32'h65626F67;	// "ebog"
	localparam CORE_VERSION   = 32'h302E3130;	// "0.10"


		//----------------------------------------------------------------
		// Control register
		//----------------------------------------------------------------
	reg	[2:0]	reg_ctrl;			// core input
	reg	[9:0]	reg_block_bits;	// input block length in bits
	reg			reg_mode;			// long/short mode
	

		//----------------------------------------------------------------
		// Init, Update and Final 1-Cycle Pulses
		//----------------------------------------------------------------
	reg	[2:0]	reg_ctrl_dly;
	always @(posedge clk) reg_ctrl_dly <= reg_ctrl;

	wire core_init_pulse		= (reg_ctrl[CTRL_INIT_BIT]   == 1'b1) && (reg_ctrl_dly[CTRL_INIT_BIT]   == 1'b0);
	wire core_update_pulse	= (reg_ctrl[CTRL_UPDATE_BIT] == 1'b1) && (reg_ctrl_dly[CTRL_UPDATE_BIT] == 1'b0);
	wire core_final_pulse	= (reg_ctrl[CTRL_FINAL_BIT]  == 1'b1) && (reg_ctrl_dly[CTRL_FINAL_BIT]  == 1'b0);


		//----------------------------------------------------------------
		// Status register
		//----------------------------------------------------------------
	wire  core_ready;		// core output
	wire  digest_valid;	// core output

	wire [1:0] reg_status = {digest_valid, core_ready};


		//----------------------------------------------------------------
		// Block and Digest
		//----------------------------------------------------------------
	reg  [511 : 0] core_block;		// core input
	wire [511 : 0] core_digest;	// core output


	//----------------------------------------------------------------
	// core instantiation.
	//----------------------------------------------------------------
	streebog_hash_top streebog
	(
		.clock			(clk),
		
		.block			(core_block),
		.block_length	(reg_block_bits),
		
		.init				(core_init_pulse),
		.update			(core_update_pulse),
		.final			(core_final_pulse),
		
		.short_mode		(reg_mode),
		
		.digest			(core_digest),
		.digest_valid	(digest_valid),
		
		.ready			(core_ready)
	);

		//----------------------------------------------------------------
		// Read Latch
		//----------------------------------------------------------------
	reg [31: 0] tmp_read_data;

	assign read_data = tmp_read_data;


	//----------------------------------------------------------------
	// Read/Write Interface
	//----------------------------------------------------------------
	always @(posedge clk)
		//
		if (rst) begin
			//
			reg_ctrl			<= 3'b000;
			reg_block_bits	<= 10'd0;
			reg_mode			<= 1'b0;
			core_block		<= {512{1'b0}};
			tmp_read_data	<= 32'h00000000;
			//
		end else if (cs) begin
			//
			if (we) begin
				//
				// Write Handler
				//
				case (address)
					ADDR_CTRL:			reg_ctrl					<= write_data[2:0];
					ADDR_BLOCK_BITS:	reg_block_bits			<= write_data[9:0];
					ADDR_MODE:			reg_mode					<= write_data[0];
					ADDR_BLOCK0:		core_block[511:480]	<= write_data;
					ADDR_BLOCK1:		core_block[479:448]	<= write_data;
					ADDR_BLOCK2:		core_block[447:416]	<= write_data;
					ADDR_BLOCK3:		core_block[415:384]	<= write_data;
					ADDR_BLOCK4:		core_block[383:352]	<= write_data;
					ADDR_BLOCK5:		core_block[351:320]	<= write_data;
					ADDR_BLOCK6:		core_block[319:288]	<= write_data;
					ADDR_BLOCK7:		core_block[287:256]	<= write_data;
					ADDR_BLOCK8:		core_block[255:224]	<= write_data;
					ADDR_BLOCK9:		core_block[223:192]	<= write_data;
					ADDR_BLOCK10:		core_block[191:160]	<= write_data;
					ADDR_BLOCK11:		core_block[159:128]	<= write_data;
					ADDR_BLOCK12:		core_block[127: 96]	<= write_data;
					ADDR_BLOCK13:		core_block[ 95: 64]	<= write_data;
					ADDR_BLOCK14:		core_block[ 63: 32]	<= write_data;
					ADDR_BLOCK15:		core_block[ 31:  0]	<= write_data;
				endcase
				//	
			end else begin
				//
				// Read Handler
				//
				case (address)
					//
					ADDR_NAME0:			tmp_read_data <= CORE_NAME0;
					ADDR_NAME1:			tmp_read_data <= CORE_NAME1;
					ADDR_VERSION:		tmp_read_data <= CORE_VERSION;
					ADDR_CTRL:			tmp_read_data <= {{28{1'b0}}, reg_ctrl};
					ADDR_STATUS:		tmp_read_data <= {{30{1'b0}}, reg_status};
					ADDR_BLOCK_BITS:	tmp_read_data <= {{22{1'b0}}, reg_block_bits};
					ADDR_MODE:			tmp_read_data <= {{31{1'b0}}, reg_mode};
					//
					ADDR_BLOCK0:		tmp_read_data <= core_block[511:480];
					ADDR_BLOCK1:		tmp_read_data <= core_block[479:448];
					ADDR_BLOCK2:		tmp_read_data <= core_block[447:416];
					ADDR_BLOCK3:		tmp_read_data <= core_block[415:384];
					ADDR_BLOCK4:		tmp_read_data <= core_block[383:352];
					ADDR_BLOCK5:		tmp_read_data <= core_block[351:320];
					ADDR_BLOCK6:		tmp_read_data <= core_block[319:288];
					ADDR_BLOCK7:		tmp_read_data <= core_block[287:256];
					ADDR_BLOCK8:		tmp_read_data <= core_block[255:224];
					ADDR_BLOCK9:		tmp_read_data <= core_block[223:192];
					ADDR_BLOCK10:		tmp_read_data <= core_block[191:160];
					ADDR_BLOCK11:		tmp_read_data <= core_block[159:128];
					ADDR_BLOCK12:		tmp_read_data <= core_block[127: 96];
					ADDR_BLOCK13:		tmp_read_data <= core_block[ 95: 64];
					ADDR_BLOCK14:		tmp_read_data <= core_block[ 63: 32];
					ADDR_BLOCK15:		tmp_read_data <= core_block[ 31:  0];
					//
					ADDR_DIGEST0:		tmp_read_data <= core_digest[511:480];
					ADDR_DIGEST1:		tmp_read_data <= core_digest[479:448];
					ADDR_DIGEST2:		tmp_read_data <= core_digest[447:416];
					ADDR_DIGEST3:		tmp_read_data <= core_digest[415:384];
					ADDR_DIGEST4:		tmp_read_data <= core_digest[383:352];
					ADDR_DIGEST5:		tmp_read_data <= core_digest[351:320];
					ADDR_DIGEST6:		tmp_read_data <= core_digest[319:288];
					ADDR_DIGEST7:		tmp_read_data <= core_digest[287:256];
					ADDR_DIGEST8:		tmp_read_data <= core_digest[255:224];
					ADDR_DIGEST9:		tmp_read_data <= core_digest[223:192];
					ADDR_DIGEST10:		tmp_read_data <= core_digest[191:160];
					ADDR_DIGEST11:		tmp_read_data <= core_digest[159:128];
					ADDR_DIGEST12:		tmp_read_data <= core_digest[127: 96];
					ADDR_DIGEST13:		tmp_read_data <= core_digest[ 95: 64];
					ADDR_DIGEST14:		tmp_read_data <= core_digest[ 63: 32];
					ADDR_DIGEST15:		tmp_read_data <= core_digest[ 31:  0];
					//
					default:				tmp_read_data <= 32'h00000000;
					//
				endcase
				//
			end
			//
		end


endmodule // streebog_wrapper


//======================================================================
// EOF streebog_wrapper.v
//======================================================================