UPDATE: add ciphering mechanism to SRAM wrapper
diff --git a/verilog/rtl/sram/sram_wb_wrapper.sv b/verilog/rtl/sram/sram_wb_wrapper.sv index 9b5769f..fb17ed0 100644 --- a/verilog/rtl/sram/sram_wb_wrapper.sv +++ b/verilog/rtl/sram/sram_wb_wrapper.sv
@@ -19,6 +19,8 @@ // initial version // 0.2 - 16 March 2022, Sukru Uzun // remove SRAM design +// 0.3 - 20 March 2022, Emre Goncu +// adding ciphering mechanism //----------------------------------------------------------------------------- module sram_wb_wrapper #( @@ -26,80 +28,363 @@ parameter SRAM_DATA_WD = 32 ) ( `ifdef USE_POWER_PINS - input wire vccd1 , // User area 1 1.8V supply - input wire vssd1 , // User area 1 digital ground + input wire vccd1 , // User area 1 1.8V supply + input wire vssd1 , // User area 1 digital ground `endif - input wire rst , + input wire rst , // Wishbone Interface - input wire wb_clk_i , // System clock - input wire wb_cyc_i , // strobe/request - input wire wb_stb_i , // strobe/request - input wire [ SRAM_ADDR_WD-1:0] wb_adr_i , // address - input wire wb_we_i , // write - input wire [ SRAM_DATA_WD-1:0] wb_dat_i , // data output - input wire [SRAM_DATA_WD/8-1:0] wb_sel_i , // byte enable - // output wire [SRAM_DATA_WD-1:0] wb_dat_o, // data input - output reg wb_ack_o , // acknowlegement + input wire wb_clk_i , // System clock + input wire wb_cyc_i , // strobe/request + input wire wb_stb_i , // strobe/request + input wire [ SRAM_ADDR_WD-1:0] wb_adr_i , // address + input wire wb_we_i , // write + input wire [ SRAM_DATA_WD-1:0] wb_dat_i , // data output + input wire [SRAM_DATA_WD/8-1:0] wb_sel_i , // byte enable + output wire [ SRAM_DATA_WD-1:0] wb_dat_o , // data input + output reg wb_ack_o , // acknowlegement // SRAM Interface // Port A - output wire sram_csb_a , - output wire [ SRAM_ADDR_WD-1:0] sram_addr_a, + output wire sram_csb_a , + output wire [ SRAM_ADDR_WD-1:0] sram_addr_a , + input wire [ SRAM_DATA_WD-1:0] sram_dout_a , // Port B - output wire sram_csb_b , - output wire sram_web_b , - output wire [SRAM_DATA_WD/8-1:0] sram_mask_b, - output wire [ SRAM_ADDR_WD-1:0] sram_addr_b, - output wire [ SRAM_DATA_WD-1:0] sram_din_b + output reg sram_csb_b , + output reg sram_web_b , + output reg [SRAM_DATA_WD/8-1:0] sram_mask_b , + output reg [ SRAM_ADDR_WD-1:0] sram_addr_b , + output reg [ SRAM_DATA_WD-1:0] sram_din_b , + input wire [ 31:0] trng_i , + input wire alarm ); -// // Port A -// wire sram_clk_a; -// wire sram_csb_a; -// wire [SRAM_ADDR_WD-1:0] sram_addr_a; -// wire [SRAM_DATA_WD-1:0] sram_dout_a; -// // Port B -// wire sram_clk_b; -// wire sram_csb_b; -// wire sram_web_b; -// wire [SRAM_DATA_WD/8-1:0] sram_mask_b; -// wire [SRAM_ADDR_WD-1:0] sram_addr_b; -// wire [SRAM_DATA_WD-1:0] sram_din_b; + logic master_key_en ; + logic [ 31:0] master_key_array[3:0]; + logic [127:0] master_key ; + logic [ 1:0] counter ; + logic [ 4:0] trng_count ; -// Memory Write Port -// assign sram_clk_b = wb_clk_i; - assign sram_csb_b = !wb_stb_i; - assign sram_web_b = !wb_we_i; - assign sram_mask_b = wb_sel_i; - assign sram_addr_b = wb_adr_i; - assign sram_din_b = wb_dat_i; + assign master_key = {master_key_array[0], master_key_array[1], master_key_array[2], master_key_array[3]}; -// Memory Read Port -// assign sram_clk_a = wb_clk_i; - assign sram_csb_a = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1) ? 1'b0 : 1'b1; - assign sram_addr_a = wb_adr_i; + assign master_key_en = rst ? 1'b0 : + (alarm || ((wb_adr_i == 32'd0) && wb_cyc_i && wb_stb_i && wb_we_i)) ? 1'b1 : 1'b0; -// assign wb_dat_o = sram_dout_a; -// sky130_sram_1kbyte_1rw1r_32x256_8 u_sram1_1kb( -// `ifdef USE_POWER_PINS -// .vccd1 (vccd1), // User area 1 1.8V supply -// .vssd1 (vssd1), // User area 1 digital ground -// `endif -// // Port 0: RW -// .clk0 (sram_clk_b), -// .csb0 (sram_csb_b), -// .web0 (sram_web_b), -// .wmask0 (sram_mask_b), -// .addr0 (sram_addr_b), -// .din0 (sram_din_b), -// .dout0 (), // dont read from Port B -// // Port 1: R -// .clk1 (sram_clk_a), -// .csb1 (sram_csb_a), -// .addr1 (sram_addr_a), -// .dout1 (sram_dout_a) -// ); + + always @(posedge wb_clk_i) begin + if(rst) + begin + master_key_array[0] <= 32'd0; + master_key_array[1] <= 32'd0; + master_key_array[2] <= 32'd0; + master_key_array[3] <= 32'd0; + counter <= 2'd0; + trng_count <= 5'd0; + end + else + begin + if(master_key_en) + begin + if(wb_dat_i) + begin + master_key_array[counter] <= wb_dat_i; + counter <= counter + 2'd1; + end + else + begin + if(trng_count == 5'd0) + begin + master_key_array[counter] <= trng_in; + counter <= counter + 2'd1; + end + trng_count <= trng_count + 5'd1; + end + end + end + + end + + + assign wb_dat_o = (wb_adr_i == 9'd1 && wb_cyc_i && wb_stb_i && !wb_we_i) ? SRAM_data_reg : + (wb_adr_i == 9'd2 && wb_cyc_i && wb_stb_i && !wb_we_i) ? {30'd0,rd_busy, wr_busy} : 'h0; + + + + + + + + /* FSM for reading ciphered Data from SRAM */ + /*******************************************/ + + localparam INIT = 0; + localparam READ_DATA = 1; + localparam WAIT_AES_READY = 2; + localparam WAIT_AES_DONE = 3; + localparam WR_TO_SRAM = 4; + + + logic [ 1:0] state_next_rd, state_reg_rd; + logic [ 8:0] sram_addr_a_next, sram_addr_a_reg; + logic [ 2:0] read_count_next, read_count_reg; + logic [31:0] read_data_next [3:0]; + logic [31:0] read_data_reg [3:0]; + logic [31:0] SRAM_data_next, SRAM_data_reg; + + logic read ; + logic aes_init_rd; + logic enc_dec_rd ; + logic aes_next_rd; + logic [127:0] aes_ptx_rd ; + logic rd_busy ; + logic aes_ready ; + logic aes_valid ; + logic [127:0] aes_ctx ; + always @(posedge wb_clk_i ) + begin + if(reset) + begin + state_reg_rd <= 2'd0; + sram_addr_a_reg <= 9'd0; + read_data_reg[0] <= 32'd0; + read_data_reg[1] <= 32'd0; + read_data_reg[2] <= 32'd0; + read_data_reg[3] <= 32'd0; + SRAM_data_reg <= 32'd0; + read_count_reg <= 3'd0; + end + else + begin + state_reg_rd <= state_next_rd; + sram_addr_a_reg <= sram_addr_a_next; + read_data_reg[0] <= read_data_next[0]; + read_data_reg[1] <= read_data_next[1]; + read_data_reg[2] <= read_data_next[2]; + read_data_reg[3] <= read_data_next[3]; + SRAM_data_reg <= SRAM_data_next ; + read_count_reg <= read_count_next ; + end + + end + + assign read = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1 && !wr_busy) ? 1'b0 : 1'b1; + always @(*) + begin + //default assignments + rd_busy = 1'b1; + state_next_rd = state_reg_rd; + sram_addr_a_next = sram_addr_a_reg; + sram_csb_a = 1'b1; + read_count_next = read_count_reg; + read_data_next[0] = read_data_reg[0]; + read_data_next[1] = read_data_reg[1]; + read_data_next[2] = read_data_reg[2]; + read_data_next[3] = read_data_reg[3]; + SRAM_data_next = SRAM_data_reg; + aes_next_rd = 1'b0; + enc_dec_rd = 1'b0; + aes_init_rd = 1'b0; + + + case (state_reg_rd) + INIT : + begin + if(read) + begin + sram_addr_a_next = wb_adr_i; + state_next_rd = READ_DATA; + end + else + rd_busy = 1'b0; + end + READ_DATA : + begin + if(read_count_reg < 3'd5) + begin + sram_addr_a_next = sram_addr_a_reg + 1; + sram_csb_a = 1'b0; + read_count_next = read_count_reg + 1; + if(read_count_reg > 3'd0) + read_data_next[read_count-1] = sram_dout_a; + end + else + begin + state_next_rd = WAIT_AES_READY; + aes_init_rd = 1'b1; + enc_dec_rd = 1'b0; + read_count_next = 3'd0; + end + end + WAIT_AES_READY : + begin + if(aes_ready) + begin + state_next_rd = WAIT_AES_DONE; + aes_next_rd = 1'b1; + aes_ptx_rd = read_data_reg; + end + end + WRITE_AES_DONE : + begin + if(aes_valid) + begin + rd_busy = 1'b0; + state_next_rd = INIT; + SRAM_data_next = aes_ctx[31:0]; + end + end + endcase + end + /* FSM for reading ciphered Data from SRAM */ + /*******************************************/ + + + + + + /* FSM for writing ciphered Data to SRAM */ + /*******************************************/ + + logic [ 2:0] state_next_wr, state_reg_wr; + logic [ 8:0] sram_addr_b_next, sram_addr_b_reg; + logic [ 2:0] wr_count_next, wr_count_reg; + logic [31:0] wr_data_next, wr_data_reg; + logic [ 8:0] wr_addr_next, wr_addr_reg; + + + logic write ; + logic aes_init_wr ; + logic enc_dec_wr ; + logic aes_next_wr ; + logic aes_ptx_wr ; + logic wr_busy ; + logic [31:0] aes_ctx_wr [3:0]; + + assign aes_ctx_wr[0] = aex_ctx[31:0]; + assign aes_ctx_wr[1] = aex_ctx[63:32]; + assign aes_ctx_wr[2] = aex_ctx[95:64]; + assign aes_ctx_wr[3] = aex_ctx[127:96]; + + assign write = (wb_stb_i == 1'b1 && wb_we_i == 1'b1 && wb_cyc_i == 1'b1 && !rd_busy) ? 1'b0 : 1'b1; + + always @(posedge wb_clk_i ) + begin + if(reset) + begin + state_reg_wr <= INIT; + wr_data_reg <= 32'd0; + wr_addr_reg <= 9'd0; + wr_count_reg <= 3'd0; + end + else + begin + state_reg_wr <= state_next_wr ; + wr_data_reg <= wr_data_next ; + wr_addr_reg <= wr_addr_next ; + wr_count_reg <= wr_count_next ; + end + end + + + + always @(*) + begin + //default assignments + wr_busy = 1'b1; + state_next_wr = state_reg_wr; + sram_addr_b = 9'd0; + sram_csb_b = 1'b1; + sram_mask_b = 4'h0; + wr_count_next = wr_count_reg; + aes_next_wr = 1'b0; + enc_dec_wr = 1'b0; + aes_init_wr = 1'b0; + wr_data_next = wr_data_reg; + wr_addr_next = wr_addr_reg; + + case (state_reg_rd) + INIT : + begin + if(write) + begin + aes_init_wr = 1'b1; + enc_dec_wr = 1'b1; + state_next_wr = WAIT_AES_READY; + wr_data_next = wb_dat_i; + wr_addr_next = wb_adr_i; + end + else + wr_busy = 1'b0; + end + WAIT_AES_READY : + begin + if(aes_ready) + begin + state_next_wr = WAIT_AES_DONE; + aes_next_wr = 1'b1; + aes_ptx_wr = wr_data_reg; + end + end + WRITE_AES_DONE : + begin + if(aes_valid) + begin + state_next_wr = WR_TO_SRAM; + sram_addr_b = wr_addr_reg; + sram_din_b = aes_ctx_wr[wr_count_reg]; + sram_csb_b = 1'b0; + sram_web_b = 1'b0; + sram_mask_b = 4'hF; + wr_count_next = wr_count_reg + 1; + end + end + WR_TO_SRAM : + begin + if(wr_count_reg < 4) + begin + sram_addr_b = wr_addr_reg + wr_count_reg; + sram_din_b = aes_ctx_wr[wr_count_reg]; + sram_csb_b = 1'b0; + sram_web_b = 1'b0; + sram_mask_b = 4'hF; + wr_count_next = wr_count_reg + 1; + end + else + begin + wr_busy = 1'b0; + wr_count_next = 3'd0; + state_next_wr = INIT; + end + end + + + endcase + end + /* FSM for writing ciphered Data to SRAM */ + /*******************************************/ + + logic aes_init = (write && !read) ? aes_init_wr : (!write && read) ? aes_init_rd : 'h0; + logic aes_next = (write && !read) ? aes_next_wr : (!write && read) ? aes_next_rd : 'h0; + logic [127:0] aes_ptx = (write && !read) ? aes_ptx_wr : (!write && read) ? aes_ptx_rd : 'h0 ; + logic enc_dec = (write && !read) ? enc_dec_wr : (!write && read) ? enc_dec_rd : 'h0 ; + + + aes_core core ( + .clk (wb_clk_i ), + .reset_n (~rst ), + + .encdec (enc_dec ), + .init (aes_init ), + .next (aes_next ), + .ready (aes_ready ), + + .key ({128'd0, master_key}), + .keylen (2'd0 ), + + .block (aes_ptx ), + .result (aes_ctx ), + .result_valid(aes_valid ) + ); // Generate once cycle delayed ACK to get the data from SRAM always @(posedge wb_clk_i)