Skip to content
Snippets Groups Projects
Commit e1f93223 authored by dam1n19's avatar dam1n19
Browse files

Added aes specific files back in

parent 9045a8d8
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,7 @@
#-----------------------------------------------------------------------------
# Accelerator Engine -- Add Your Accelerator Environment Variable HERE!
#export ACCELERATOR_DIR="$SOCLABS_PROJECT_DIR/youraccelerator"
export ACCELERATOR_DIR="$SOCLABS_PROJECT_DIR/secworks-aes"
# Accelerator Wrapper
export SOCLABS_WRAPPER_TECH_DIR="$SOCLABS_PROJECT_DIR/accelerator_wrapper_tech"
......
......@@ -14,10 +14,10 @@
// ============= Accelerator Module search path =============
// ! Point this to your Accelerator RTL
//+incdir+$(ACCELERATOR_DIR)/src/rtl
+incdir+$(ACCELERATOR_DIR)/src/rtl
// ! Point this to your Wrapper RTL
//$(SOCLABS_PROJECT_DIR)/wrapper/src/your_wrapper.v
$(SOCLABS_PROJECT_DIR)/wrapper/src/soclabs_ahb_aes128_ctrl.v
// ! Point this to your Subsystem RTL
//$(SOCLABS_PROJECT_DIR)/system/src/accelerator_subsystem.v
\ No newline at end of file
$(SOCLABS_PROJECT_DIR)/system/src/accelerator_subsystem.v
\ No newline at end of file
......@@ -11,6 +11,7 @@
# Each Repo needs to have its branch set manually in here - they will defaultly be checked out to main
# Project Repository Subrepository Branch Index
# Add your Accelerator Repository here
secworks-aes: master
nanosoc_tech: main
accelerator_wrapper_tech: main
......
//-----------------------------------------------------------------------------
// SoC Labs Accelerator Subsystem for SecWorks AES-128 Accelerator
// A joint work commissioned on behalf of SoC Labs; under Arm Academic Access license.
//
// Contributors
//
// David Mapstone (d.a.mapstone@soton.ac.uk)
// David Flynn (d.w.flynn@soton.ac.uk)
//
// Copyright (C) 2023; SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
module accelerator_subsystem #(
parameter SYS_ADDR_W = 32,
parameter SYS_DATA_W = 32,
parameter ACC_ADDR_W = 16,
parameter IRQ_NUM = 4
) (
input wire HCLK, // Clock
input wire HRESETn, // Reset
// AHB connection to Initiator
input wire HSEL,
input wire [SYS_ADDR_W-1:0] HADDR,
input wire [1:0] HTRANS,
input wire [2:0] HSIZE,
input wire [3:0] HPROT,
input wire HWRITE,
input wire HREADY,
input wire [SYS_DATA_W-1:0] HWDATA,
output wire HREADYOUT,
output wire HRESP,
output wire [SYS_DATA_W-1:0] HRDATA,
// Data Request Signal to DMAC
output wire [1:0] EXP_DRQ,
input wire [1:0] EXP_DLAST,
// Interrupts
output wire [IRQ_NUM-1:0] EXP_IRQ
);
//--------------------------------------
// AES Accelerator Wrapper
//--------------------------------------
soclabs_ahb_aes128_ctrl u_exp_aes128 (
.ahb_hclk (HCLK),
.ahb_hresetn (HRESETn),
.ahb_hsel (HSEL),
.ahb_haddr16 (HADDR[ACC_ADDR_W-1:0]),
.ahb_htrans (HTRANS),
.ahb_hwrite (HWRITE),
.ahb_hsize (HSIZE),
.ahb_hprot (HPROT),
.ahb_hwdata (HWDATA),
.ahb_hready (HREADY),
.ahb_hrdata (HRDATA),
.ahb_hreadyout (HREADYOUT),
.ahb_hresp (HRESP),
.drq_ipdma128 (EXP_DRQ[0]),
.dlast_ipdma128 (EXP_DLAST[0]),
.drq_opdma128 (EXP_DRQ[1]),
.dlast_opdma128 (EXP_DLAST[1]),
.irq_key128 (EXP_IRQ[0]),
.irq_ip128 (EXP_IRQ[1]),
.irq_op128 (EXP_IRQ[2]),
.irq_error (EXP_IRQ[3]),
.irq_merged ( )
);
endmodule
//-----------------------------------------------------------------------------
// top-level soclabs example AHB interface
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Flynn (d.w.flynn@soton.ac.uk)
//
// Copyright (C) 2023, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
module soclabs_ahb_aes128_ctrl(
// -------------------------------------------------------
// MCU interface
// -------------------------------------------------------
input wire ahb_hclk, // Clock
input wire ahb_hresetn, // Reset
input wire ahb_hsel, // Device select
input wire [15:0] ahb_haddr16, // Address for byte select
input wire [1:0] ahb_htrans, // Transfer control
input wire [2:0] ahb_hsize, // Transfer size
input wire [3:0] ahb_hprot, // Protection control
input wire ahb_hwrite, // Write control
input wire ahb_hready, // Transfer phase done
input wire [31:0] ahb_hwdata, // Write data
output wire ahb_hreadyout, // Device ready
output wire [31:0] ahb_hrdata, // Read data output
output wire ahb_hresp, // Device response
// stream data
output wire drq_ipdma128, // (to) DMAC input burst request
input wire dlast_ipdma128,// (from) DMAC input burst end (last transfer)
output wire drq_opdma128, // (to) DMAC output dma burst request
input wire dlast_opdma128,// (from) DMAC output burst end (last transfer)
output wire irq_key128,
output wire irq_ip128,
output wire irq_op128,
output wire irq_error,
output wire irq_merged // combined interrrupt request (to CPU)
);
//----------------------------------------------------------------
// Internal parameter definitions.
//----------------------------------------------------------------
///typedef struct {
/// __I uint32_t CORE_NAME[2]; /* 0x0000-0007 */
/// __I uint32_t CORE_VERSION; /* 0x0008-000B */
/// uint32_t RESRV0C; /* 0x000C */
/// __IO uint32_t CTRL; /* 0x0010 */
/// __O uint32_t CTRL_SET; /* 0x0014 */
/// __O uint32_t CTRLL_CLR; /* 0x0018 */
/// __I uint32_t STATUS; /* 0x001c */
/// __IO uint32_t QUAL; /* 0x0020 */
/// uint32_t RESRV24[3]; /* 0x0024 - 2F*/
/// __IO uint32_t DRQ_MSK; /* 0x0030 */
/// __O uint32_t DRQ_MSK_SET; /* 0x0034 */
/// __O uint32_t DRQ_MSK_CLR; /* 0x0038 */
/// __I uint32_t DRQ_STATUS; /* 0x003C */
/// __IO uint32_t IRQ_MSK; /* 0x0040 */
/// __O uint32_t IRQ_MSK_SET; /* 0x0044 */
/// __O uint32_t IRQ_MSK_CLR; /* 0x0048 */
/// __I uint32_t IRQ_STATUS; /* 0x004C */
/// uint32_t RESRV50[4076]; /* 0x0050-0x3FFC (4096-20 words) */
/// __IO uint8_t KEY128[0x4000]; /* 0x4000-7FFF (0x3FFF is last alias) */
/// __IO uint8_t TXTIP128[0x4000]; /* 0x8000-BFFF (0x3FFF is last alias) */
/// __I uint8_t TXTOP128[0x4000]; /* 0xC000-FFFF (0x3FFF is last alias) */
///} AES128_TypeDef;
// CORE ID
localparam ADDR_CORE_NAME0 = 16'h0000;
localparam ADDR_CORE_NAME1 = 16'h0004;
localparam ADDR_CORE_VERSION= 16'h0008;
localparam CORE_NAME0 = 32'h61657331; // "aes1"
localparam CORE_NAME1 = 32'h32382020; // "28 "
localparam CORE_VERSION = 32'h302e3031; // "0.01"
// CTRL control register with bit-set/bit-clear options
localparam ADDR_CTRL = 16'h0010;
localparam ADDR_CTRL_SET = 16'h0014;
localparam ADDR_CTRL_CLR = 16'h0018;
localparam CTRL_REG_WIDTH = 8;
localparam CTRL_BIT_MAX = (CTRL_REG_WIDTH-1);
localparam CTRL_KEY_REQ_BIT = 0;
localparam CTRL_IP_REQ_BIT = 1;
localparam CTRL_OP_REQ_BIT = 2;
localparam CTRL_ERR_REQ_BIT = 3;
localparam CTRL_KEYOK_BIT = 4;
localparam CTRL_VALID_BIT = 5;
localparam CTRL_BYPASS_BIT = 6;
localparam CTRL_ENCODE_BIT = 7;
// STAT status regisyer
localparam ADDR_STAT = 16'h001c;
localparam STAT_REG_WIDTH = 8;
localparam STAT_BIT_MAX = (STAT_REG_WIDTH-1);
localparam STAT_KEYREQ_BIT = 0;
localparam STAT_INPREQ_BIT = 1;
localparam STAT_OUTREQ_BIT = 2;
localparam STAT_ERROR_BIT = 3;
localparam STAT_KEYOK_BIT = 4;
localparam STAT_VALID_BIT = 5;
// QUAL qualifier field
localparam ADDR_QUAL = 16'h0020;
localparam QUAL_REG_WIDTH = 32;
localparam QUAL_BIT_MAX = (QUAL_REG_WIDTH-1);
// DREQ DMAC request control with bit-set/bit-clear options
localparam ADDR_DREQ = 16'h0030;
localparam ADDR_DREQ_SET = 16'h0034;
localparam ADDR_DREQ_CLR = 16'h0038;
localparam ADDR_DREQ_ACT = 16'h003c;
localparam DREQ_REG_WIDTH = 3;
localparam DREQ_BIT_MAX = (DREQ_REG_WIDTH-1);
localparam REQ_KEYBUF_BIT = 0;
localparam REQ_IP_BUF_BIT = 1;
localparam REQ_OP_BUF_BIT = 2;
// IREQ CPU interrupt request control with bit-set/bit-clear options
localparam ADDR_IREQ = 16'h0040;
localparam ADDR_IREQ_SET = 16'h0044;
localparam ADDR_IREQ_CLR = 16'h0048;
localparam ADDR_IREQ_ACT = 16'h004c;
localparam IREQ_REG_WIDTH = 4;
localparam IREQ_BIT_MAX = (IREQ_REG_WIDTH-1);
localparam REQ_ERROR_BIT = 3;
localparam ADDR_KEY_BASE = 16'h4000;
localparam ADDR_KEY0 = 16'h4000;
localparam ADDR_KEY3 = 16'h400c;
localparam ADDR_KEY7 = 16'h401c;
localparam ADDR_IBUF_BASE = 16'h8000;
localparam ADDR_IBUF_0 = 16'h8000;
localparam ADDR_IBUF_3 = 16'h800c;
localparam ADDR_OBUF_BASE = 16'hc000;
localparam ADDR_OBUF_3 = 16'hc00c;
// --------------------------------------------------------------------------
// Internal regs/wires
// --------------------------------------------------------------------------
reg [15:0] addr16_r;
reg sel_r;
reg wcyc_r;
reg rcyc_r;
reg [3:0] byte4_r;
wire key128_load_ack;
wire ip128_load_ack;
wire op128_load_ack;
// --------------------------------------------------------------------------
// AHB slave byte buffer interface, support for unaligned data transfers
// --------------------------------------------------------------------------
wire [1:0] byt_adr = ahb_haddr16[1:0];
// generate next byte enable decodes for Word/Half/Byte CPU/DMA accesses
wire [3:0] byte_nxt;
assign byte_nxt[0] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b00);
assign byte_nxt[1] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b01);
assign byte_nxt[2] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b10);
assign byte_nxt[3] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b11);
// de-pipelined registered access signals
always @(posedge ahb_hclk or negedge ahb_hresetn)
if (!ahb_hresetn)
begin
addr16_r <= 16'h0000;
sel_r <= 1'b0;
wcyc_r <= 1'b0;
rcyc_r <= 1'b0;
byte4_r <= 4'b0000;
end else if (ahb_hready)
begin
addr16_r <= (ahb_hsel & ahb_htrans[1]) ? ahb_haddr16 : addr16_r;
sel_r <= (ahb_hsel & ahb_htrans[1]);
wcyc_r <= (ahb_hsel & ahb_htrans[1] & ahb_hwrite);
rcyc_r <= (ahb_hsel & ahb_htrans[1] & !ahb_hwrite);
byte4_r <= (ahb_hsel & ahb_htrans[1]) ? byte_nxt[3:0] : 4'b0000;
end
// pipelined "early" last access decodes, for PL230 dma_ack timing to deassert dma requests
// wire ahb128_last = ahb_hsel & ahb_htrans[1] & ahb_hready & ahb_haddr16[3] & ahb_haddr16[2] & byte_nxt[3];
// wire ahb128_wlast = ahb_last & ahb_hwrite & |ahb_haddr[15:14]; // address phase of last write transfer
// wire ahb128_rlast = ahb_last & !ahb_hwrite & |ahb_haddr[15:14]; // address phase of last read transfer
wire wlast128 = |ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & wcyc_r; // write last pulse
wire rlast128 = &ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & rcyc_r; // read last pulse
//----------------------------------------------------------------
// API register state and wiring
//
//----------------------------------------------------------------
reg [CTRL_BIT_MAX:0] control;
reg [QUAL_BIT_MAX:0] param;
reg [DREQ_BIT_MAX:0] drq_enable;
reg [IREQ_BIT_MAX:0] irq_enable;
wire [STAT_BIT_MAX:0] status;
wire [DREQ_BIT_MAX:0] drq_active;
wire [IREQ_BIT_MAX:0] irq_active;
wire [31:0] rd_keybuf;
wire [31:0] rd_ipbuf;
wire [31:0] rd_opbuf;
//----------------------------------------------------------------
// API write decoder
//
//----------------------------------------------------------------
wire sel_mode = sel_r & (addr16_r[15: 8] == 0);
wire sel_keybuf = sel_r & (addr16_r[15:14] == 1);
wire sel_ipbuf = sel_r & (addr16_r[15:14] == 2);
wire sel_opbuf = sel_r & (addr16_r[15:14] == 3);
// add address map "last" transfer signalling when last (byte) of alias map is written
wire alast_key128 = sel_keybuf & wcyc_r & (&addr16_r[13:2]) & byte4_r[3];
wire alast_ip128 = sel_ipbuf & wcyc_r & (&addr16_r[13:2]) & byte4_r[3];
wire alast_op128 = sel_opbuf & rcyc_r & (&addr16_r[13:2]) & byte4_r[3];
always @(posedge ahb_hclk or negedge ahb_hresetn)
if (!ahb_hresetn) begin
control <= {CTRL_REG_WIDTH{1'b0}};
param <= {QUAL_REG_WIDTH{1'b0}};
drq_enable <= {DREQ_REG_WIDTH{1'b0}};
irq_enable <= {IREQ_REG_WIDTH{1'b0}};
end
else if (sel_mode & wcyc_r & byte4_r[0])
case ({addr16_r[15:2],2'b00})
ADDR_CTRL : control <= ahb_hwdata[CTRL_BIT_MAX:0]; // overwrite ctl reg
ADDR_CTRL_SET: control <= ahb_hwdata[CTRL_BIT_MAX:0] | control; // bit set ctl mask pattern
ADDR_CTRL_CLR: control <= ~ahb_hwdata[CTRL_BIT_MAX:0] & control; // bit clear ctl mask pattern
ADDR_QUAL : param <= ahb_hwdata[QUAL_BIT_MAX:0]; // write qual pattern
ADDR_DREQ : drq_enable <= ahb_hwdata[DREQ_BIT_MAX:0]; // overwrite dreq reg
ADDR_DREQ_SET: drq_enable <= ahb_hwdata[DREQ_BIT_MAX:0] | drq_enable; // bit set dreq mask pattern
ADDR_DREQ_CLR: drq_enable <= ~ahb_hwdata[DREQ_BIT_MAX:0] & drq_enable; // bit clear dreq mask pattern
ADDR_IREQ : irq_enable <= ahb_hwdata[IREQ_BIT_MAX:0]; // overwrite ireq reg
ADDR_IREQ_SET: irq_enable <= ahb_hwdata[IREQ_BIT_MAX:0] | irq_enable; // bit set ireq mask pattern
ADDR_IREQ_CLR: irq_enable <= ~ahb_hwdata[IREQ_BIT_MAX:0] & irq_enable; // bit clear ireq mask pattern
default: ;
endcase
else if (sel_keybuf & wcyc_r & (dlast_ipdma128 | alast_key128)) // key terminate
drq_enable[0] <= 1'b0;
else if (sel_ipbuf & wcyc_r & (dlast_ipdma128 | alast_ip128)) // ip-buffer terminate
drq_enable[1] <= 1'b0;
else if (sel_opbuf & rcyc_r & (dlast_opdma128 | alast_op128)) // op-buffer complete
drq_enable[2] <= 1'b0;
//----------------------------------------------------------------
// API read decoder
//
//----------------------------------------------------------------
reg [31:0] rdata32; // mux read data
always @*
begin : read_decoder
rdata32 = 32'hbad0bad;
if (sel_r & rcyc_r)
case ({addr16_r[15:2],2'b00})
ADDR_CORE_NAME0 : rdata32 = CORE_NAME0;
ADDR_CORE_NAME1 : rdata32 = CORE_NAME1;
ADDR_CORE_VERSION : rdata32 = CORE_VERSION;
ADDR_CTRL : rdata32 = {{(32-CTRL_REG_WIDTH){1'b0}}, control};
ADDR_STAT : rdata32 = {{(32-STAT_REG_WIDTH){1'b0}}, status};
ADDR_QUAL : rdata32 = {{(32-QUAL_REG_WIDTH){1'b0}}, param};
ADDR_DREQ : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_enable};
ADDR_DREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_active};
ADDR_IREQ : rdata32 = {{(32-IREQ_REG_WIDTH){1'b0}}, irq_enable};
ADDR_IREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, irq_active};
default:
if (sel_keybuf) rdata32 = rd_keybuf;
else if (sel_ipbuf) rdata32 = rd_ipbuf;
else if (sel_opbuf) rdata32 = rd_opbuf;
endcase
end // read_decoder
assign ahb_hrdata = rdata32;
assign ahb_hreadyout = 1'b1; // zero wait state interface
assign ahb_hresp = 1'b0;
// --------------------------------------------------------------------------
// Key Input Buffer - keybuf
// --------------------------------------------------------------------------
wire [127:0] key128_be;
soclabs_iobuf_reg128
#(.WRITE_ONLY (1),
.WRITE_ZPAD (0))
u_reg128_key
(
.clk (ahb_hclk ), // Clock
.rst_b (ahb_hresetn ), // Reset
.sel_r (sel_keybuf ), // Bank decode select
.wcyc_r (wcyc_r ), // Write cycle (wdata32 valid)
.rcyc_r (rcyc_r ), // Read cycle (return rdata32)
.word2_r (addr16_r[3:2] ), // Address for word select
.byte4_r (byte4_r[3:0] ), // Byte select decoded (up to 4 enabled)
.wdata32 (ahb_hwdata[31:0]), // Write data (byte lane qualified)
.rdata32 (rd_keybuf ), // Read data output
.dma128_ack (key128_load_ack ), // DMA burst acknowledge
.out128_le ( ), // Big-Endian 128-bit value
.out128_be (key128_be ) // Big-Endian 128-bit value
);
// --------------------------------------------------------------------------
// Data Input Buffer - ipbuf
// --------------------------------------------------------------------------
wire [127:0] ip128_le;
wire [127:0] ip128_be;
soclabs_iobuf_reg128
#(.WRITE_ONLY (0),
.WRITE_ZPAD (1))
u_reg128_ip
(
.clk (ahb_hclk ), // Clock
.rst_b (ahb_hresetn ), // Reset
.sel_r (sel_ipbuf ), // Bank decode select
.wcyc_r (wcyc_r ), // Write cycle (wdata32 valid)
.rcyc_r (rcyc_r ), // Read cycle (return rdata32)
.word2_r (addr16_r[3:2] ), // Address for word select
.byte4_r (byte4_r[3:0] ), // Byte select decoded (up to 4 enabled)
.wdata32 (ahb_hwdata[31:0]), // Write data (byte lane qualified)
.rdata32 (rd_ipbuf ), // Read data output
.dma128_ack (ip128_load_ack ), // DMA burst acknowledge
.out128_le (ip128_le ), // Big-Endian 128-bit value
.out128_be (ip128_be ) // Big-Endian 128-bit value
);
// --------------------------------------------------------------------------
// Data Output Buffer - opbufsel_keybuf
// --------------------------------------------------------------------------
wire [127:0] op128_be;
wire [127:0] op128_muxed = (control[CTRL_BYPASS_BIT]) ? ip128_be : op128_be;
wire [31:0] op_slice32 [0:3];
assign op_slice32[3] = {op128_muxed[ 7: 0],op128_muxed[ 15: 8],op128_muxed[ 23: 16],op128_muxed[ 31: 24]};
assign op_slice32[2] = {op128_muxed[ 39: 32],op128_muxed[ 47: 40],op128_muxed[ 55: 48],op128_muxed[ 63: 56]};
assign op_slice32[1] = {op128_muxed[ 71: 64],op128_muxed[ 79: 72],op128_muxed[ 87: 80],op128_muxed[ 95: 88]};
assign op_slice32[0] = {op128_muxed[103: 96],op128_muxed[111:104],op128_muxed[119:112],op128_muxed[127:120]};
// 32-bit addressed read data
assign rd_opbuf = op_slice32[addr16_r[3:2]];
assign op128_load_ack = (sel_opbuf & rcyc_r & addr16_r[3] & addr16_r[2] & byte4_r[3]);
// --------------------------------------------------------------------------
// example aes128 engine timing
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// AES-specific control interface
// --------------------------------------------------------------------------
wire aes128_encode = control[CTRL_ENCODE_BIT];
wire aes256_keysize = 1'b0;
wire aes_keyloaded_pulse = key128_load_ack; // pulse on last byte load of key128
wire aes_dataloaded_pulse= ip128_load_ack; // pulse on last byte load of text128
wire aes_ready;
wire aes_valid;
// state machine control
reg aes_ready_del;
reg aes_init;
reg aes_next;
reg aes_key_busy;
reg aes_key_rdy;
reg aes_res_busy;
reg aes_res_rdy;
reg aes_err;
always @(posedge ahb_hclk or negedge ahb_hresetn)
if (!ahb_hresetn) begin
aes_ready_del <= 1'b0;
aes_init <= 1'b0;
aes_next <= 1'b0;
aes_key_busy <= 1'b0;
aes_key_rdy <= 1'b0;
aes_res_busy <= 1'b0;
aes_res_rdy <= 1'b0;
aes_err <= 1'b0;
end else begin
aes_ready_del <= aes_ready; // delay for rising edge detect
aes_init <= aes_keyloaded_pulse;
aes_next <= aes_dataloaded_pulse;
aes_key_busy <= (aes_init) | (aes_key_busy & !(aes_ready & !aes_ready_del)); // hold until key expansion done
aes_key_rdy <= (aes_key_busy & aes_ready & !aes_ready_del) // expanded key ready
| (aes_key_rdy & !(sel_keybuf & wcyc_r)); // hold until any key update
aes_res_busy <= (aes_next) | (aes_res_busy & !(aes_ready & !aes_ready_del)); // hold until block processing done
aes_res_rdy <= (aes_res_busy & aes_ready & !aes_ready_del) // block ready
| (aes_res_rdy & !op128_load_ack); // hold until output transferred
aes_err <= (!aes_key_rdy & ((sel_ipbuf & wcyc_r) | (sel_opbuf & rcyc_r)))
| (aes_err & !(sel_keybuf & wcyc_r));
end
assign drq_active[REQ_KEYBUF_BIT] = control[CTRL_KEY_REQ_BIT] & (!aes_keyloaded_pulse & !aes_init & !aes_key_busy & !aes_key_rdy);
assign drq_active[REQ_IP_BUF_BIT] = control[CTRL_IP_REQ_BIT] & (!aes_dataloaded_pulse & !aes_next & !aes_res_busy & !aes_res_rdy & aes_key_rdy);
assign drq_active[REQ_OP_BUF_BIT] = control[CTRL_OP_REQ_BIT] & (!aes_res_busy & aes_res_rdy);
// input DMA channel shared by Key and Data-In
assign drq_ipdma128 = (drq_enable[REQ_KEYBUF_BIT] & drq_active[REQ_KEYBUF_BIT] & !wlast128) // if key DMA enabled
| (drq_enable[REQ_IP_BUF_BIT] & drq_active[REQ_IP_BUF_BIT] & !wlast128) // if ip128 DMA requested
;
// output DMA channel for Data-Out
assign drq_opdma128 = (drq_enable[REQ_OP_BUF_BIT] & drq_active[REQ_OP_BUF_BIT] & !rlast128); // if op128 DMA requested
// and Interrupt requests are masked out if corresponding DMA requests are enabled
assign irq_active[REQ_KEYBUF_BIT] = drq_active[REQ_KEYBUF_BIT] & !drq_enable[REQ_KEYBUF_BIT];
assign irq_active[REQ_IP_BUF_BIT] = drq_active[REQ_IP_BUF_BIT] & !drq_enable[REQ_IP_BUF_BIT];
assign irq_active[REQ_OP_BUF_BIT] = drq_active[REQ_OP_BUF_BIT] & !drq_enable[REQ_OP_BUF_BIT];
assign irq_active[REQ_ERROR_BIT ] = control[CTRL_ERR_REQ_BIT] & aes_err; // error raised in SW
assign irq_key128 = irq_active[REQ_KEYBUF_BIT] & irq_enable[REQ_KEYBUF_BIT];
assign irq_ip128 = irq_active[REQ_IP_BUF_BIT] & irq_enable[REQ_IP_BUF_BIT];
assign irq_op128 = irq_active[REQ_OP_BUF_BIT] & irq_enable[REQ_OP_BUF_BIT];
assign irq_error = irq_active[REQ_ERROR_BIT ] & irq_enable[REQ_ERROR_BIT ];
// merge and mask if not DRQ
assign irq_merged = irq_key128 | irq_ip128 | irq_op128 | irq_error;
// wire up status port
assign status[2:0] = control [2:0];
assign status[STAT_ERROR_BIT] = (!aes_res_busy & !aes_key_rdy);
assign status[STAT_KEYOK_BIT] = aes_key_rdy;
assign status[STAT_VALID_BIT] = aes_res_rdy;
assign status[7:6] = control [7:6];
//----------------------------------------------------------------
// core instantiation.
//----------------------------------------------------------------
aes_core core(
.clk(ahb_hclk),
.reset_n(ahb_hresetn),
.encdec(aes128_encode),
.init(aes_init),
.next(aes_next),
.ready(aes_ready),
.key({key128_be,key128_be}),
.keylen(aes256_keysize),
.block(ip128_be),
.result(op128_be),
.result_valid(aes_valid)
);
endmodule
module soclabs_iobuf_reg128
#(
parameter WRITE_ONLY = 0,
parameter WRITE_ZPAD = 0
) (
// -------------------------------------------------------
// de-pipelined register interface
// -------------------------------------------------------
// ahb
input wire clk, // Clock
input wire rst_b, // Reset
input wire sel_r, // Bank decode select
input wire wcyc_r, // Write cycle (wdata32 valid)
input wire rcyc_r, // Read cycle (return rdata32)
input wire [1:0] word2_r, // Address for word select
input wire [3:0] byte4_r, // Byte select decoded (up to 4 enabled)
input wire [31:0] wdata32, // Write data (byte lae qualified)
output wire [31:0] rdata32, // Read data output
output wire dma128_ack, // DMA burst acknowledge
output wire [127:0] out128_le, // Litte-Endian 128-bit value
output wire [127:0] out128_be // Big-Endian 128-bit value
) ;
reg [7:0] byte0 [0:3];
reg [7:0] byte1 [0:3];
reg [7:0] byte2 [0:3];
reg [7:0] byte3 [0:3];
reg ack128;
wire zpad_cfg = (WRITE_ZPAD==0) ? 1'b0 : 1'b1;
// byte-0 array; flush on write to word-0, byte-0
// else addressed word byte-0 write
always @(posedge clk or negedge rst_b)
if (!rst_b)
begin byte0[0] <= 8'h00; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & byte4_r[0] & !word2_r[1] & !word2_r[0]) // Z-PAD rest
begin byte0[0] <= wdata32[ 7: 0]; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end
else if (sel_r & wcyc_r & byte4_r[0])
byte0[word2_r[1:0]] <= wdata32[ 7: 0];
// byte-1 array; flush on write to word-0, byte-0 if byte-1 not also written
// flush rest on write to word-0, byte-0 and byte-1 also written
// else address word byte-1 write
always @(posedge clk or negedge rst_b)
if (!rst_b)
begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
begin byte1[0] <= wdata32[15: 8]; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
else if (sel_r & wcyc_r & byte4_r[1])
byte1[word2_r[1:0]] <= wdata32[15: 8];
// byte-2 array; flush on write to word-0, byte-0 if byte-2 not also written
// flush rest on write to word-0, byte-0 and byte-2 also written
// else address word byte-2 write
always @(posedge clk or negedge rst_b)
if (!rst_b)
begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
begin byte2[0] <= wdata32[23:16]; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
else if (sel_r & wcyc_r & byte4_r[2])
byte2[word2_r[1:0]] <= wdata32[23:16];
// byte-3 array; flush on write to word-0, byte-0 if byte-3 not also written
// flush rest on write to word-0, byte-0 and byte-3 also written
// else address word byte-3 write
always @(posedge clk or negedge rst_b)
if (!rst_b)
begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
else if (zpad_cfg & sel_r & wcyc_r & byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
begin byte3[0] <= wdata32[31:24]; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
else if (sel_r & wcyc_r & byte4_r[3])
byte3[word2_r[1:0]] <= wdata32[31:24];
// ack on write to final byte [15]
always @(posedge clk or negedge rst_b)
if (!rst_b)
ack128 <= 1'b0;
else
ack128 <= sel_r & wcyc_r & word2_r[1] & word2_r[0] & byte4_r[3];
assign dma128_ack = ack128;
// byte reverse per word for Big Endian AES engine
assign out128_be = {byte0[0], byte1[0], byte2[0], byte3[0],
byte0[1], byte1[1], byte2[1], byte3[1],
byte0[2], byte1[2], byte2[2], byte3[2],
byte0[3], byte1[3], byte2[3], byte3[3]};
// byte reverse per word for Big Endian AES engine
assign out128_le = {byte3[3], byte2[3], byte1[3], byte0[3],
byte3[2], byte2[2], byte1[2], byte0[2],
byte3[1], byte2[1], byte1[1], byte0[1],
byte3[0], byte2[0], byte1[0], byte0[0]};
// little-endian read data (if not Write-Only)
assign rdata32 = (sel_r & rcyc_r & (WRITE_ONLY == 0))
? {byte3[word2_r[1:0]], byte2[word2_r[1:0]],
byte1[word2_r[1:0]], byte0[word2_r[1:0]]}
: 32'h00000000;
endmodule
// include SecWorks IP but fix up default_nettype issues that breaks elsewhere
`include "aes_core.v"
`default_nettype wire
`include "aes_encipher_block.v"
`default_nettype wire
`include "aes_decipher_block.v"
`default_nettype wire
`include "aes_key_mem.v"
`default_nettype wire
`include "aes_sbox.v"
`default_nettype wire
`include "aes_inv_sbox.v"
`default_nettype wire
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment