1`timescale 1ns / 1ps
2/*
3 * This software is Copyright (c) 2016 Denis Burykin
4 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru]
5 * and it is hereby released to the general public under the following terms:
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted.
8 *
9 */
10
11//
12// 4x 1K S-blocks for bcrypt core
13//
14module S #(
15	parameter MSB = 31,
16	parameter ADDR_NBITS = 8
17	)(
18	input CLK,
19	input [MSB:0] din,
20	input wr_en,
21	input [9:0] addr_wr,
22
23	input rd_en,
24	input rst_rd,
25	input [MSB:0] addr_rd,
26	output [MSB:0] out
27	);
28
29	reg [MSB:0] S0 [255:0];
30	reg [MSB:0] S1 [255:0];
31	reg [MSB:0] S2 [255:0];
32	reg [MSB:0] S3 [255:0];
33
34	reg [MSB:0] S0_out = 0, S1_out = 0, S2_out = 0, S3_out = 0;
35
36	always @(posedge CLK) begin
37		// Write channel
38		if (wr_en && addr_wr[9:8] == 2'b00)
39			S0 [addr_wr[7:0]] <= din;
40		if (wr_en && addr_wr[9:8] == 2'b01)
41			S1 [addr_wr[7:0]] <= din;
42		if (wr_en && addr_wr[9:8] == 2'b10)
43			S2 [addr_wr[7:0]] <= din;
44		if (wr_en && addr_wr[9:8] == 2'b11)
45			S3 [addr_wr[7:0]] <= din;
46
47		// Read channel
48		if (rst_rd) begin
49			S0_out <= 0;
50			S1_out <= 0;
51			S2_out <= 0;
52			S3_out <= 0;
53		end
54		else if (rd_en) begin
55			S0_out <= S0 [ addr_rd[4*ADDR_NBITS-1 : 3*ADDR_NBITS] ];
56			S1_out <= S1 [ addr_rd[3*ADDR_NBITS-1 : 2*ADDR_NBITS] ];
57			S2_out <= S2 [ addr_rd[2*ADDR_NBITS-1 : ADDR_NBITS] ];
58			S3_out <= S3 [ addr_rd[ADDR_NBITS-1 : 0] ];
59		end
60	end
61
62
63	assign out = S3_out + (S2_out ^ (S1_out + S0_out));
64
65
66endmodule
67