Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • dev
  • feat_accel_decouple
  • feat_accel_hash_stream
  • feat_dma230_dataio
  • feat_dma350
  • feat_dmax4
  • feat_extio
  • feat_nanosoc_regions
  • feat_qspi_rom
  • main
  • nanosoc-2023
11 results

Target

Select target project
  • soclabs/nanosoc_tech
1 result
Select Git revision
  • dev
  • feat_accel_decouple
  • feat_accel_hash_stream
  • feat_dma230_dataio
  • feat_dma350
  • feat_dmax4
  • feat_extio
  • feat_nanosoc_regions
  • feat_qspi_rom
  • main
  • nanosoc-2023
11 results
Show changes
Commits on Source (3)
Showing
with 1671 additions and 2547 deletions
......@@ -33,18 +33,8 @@ simulate-nanosoc:
build-job-Z2: # This job runs in the build stage, which runs first.
stage: build
script:
# setup vivado environment for Vivado 2021.1
- source /tools/Xilinx/Vivado/2021.1/.settings64-Vivado.sh
# move and unpack the arm ip into the arm-AAA-ip folder, below the working directory
- cp -r /home/gitlab-runner/arm-AAA-ip ../arm-AAA-ip
- cd ../arm-AAA-ip/Corstone-101_Foundation_IP/
- tar -xf BP210-r1p1-00rel0.tar.gz
- cd ../Cortex-M0/
- tar -xf AT510-r0p0-03rel2.tar.gz
- cd ../DMA-230_MicroDMA_Controller/
- tar -xf PL230-r0p0-02rel2-1.tar.gz
# move to fpga_imp directory and run the fpga build script for pynq z2
- cd ../../nanosoc_tech/system/fpga_imp/
- cd ./system/fpga_imp/
- source ../../set_env.sh
- mkdir -p $NANOSOC_TECH_DIR/system/src/bootrom
- make -C $NANOSOC_TECH_DIR/system bootrom SIM_TOP_DIR=$NANOSOC_TECH_DIR/sim BOOTROM_BUILD_DIR=$NANOSOC_TECH_DIR/system/src/bootrom TOOL_CHAIN=ds6
......@@ -56,9 +46,6 @@ build-job-Z2: # This job runs in the build stage, which runs first.
- echo "Build failed"
- exit 1
- fi
# cleanup arm-AAA-ip directory
- cd ../../../
- rm -r arm-AAA-ip
artifacts:
paths:
# Keep the generated bit and hwh file from fpga build script
......@@ -71,16 +58,8 @@ build-job-Z2: # This job runs in the build stage, which runs first.
build-job-ZCU104: # This job runs in the build stage, which runs first.
stage: build
script:
# move and unpack the arm ip into the arm-AAA-ip folder, below the working directory
- cp -r /home/dwn1c21/arm-AAA-ip ../arm-AAA-ip
- cd ../arm-AAA-ip/Corstone-101_Foundation_IP/
- tar -xf BP210-r1p1-00rel0.tar.gz
- cd ../Cortex-M0/
- tar -xf AT510-r0p0-03rel2.tar.gz
- cd ../DMA-230_MicroDMA_Controller/
- tar -xf PL230-r0p0-02rel2-1.tar.gz
# move to fpga_imp directory and run the fpga build script for pynq z2
- cd ../../nanosoc_tech/system/fpga_imp/
- cd ./system/fpga_imp/
- source ../../set_env.sh
- mkdir -p $NANOSOC_TECH_DIR/system/src/bootrom
- make -C $NANOSOC_TECH_DIR/system bootrom SIM_TOP_DIR=$NANOSOC_TECH_DIR/sim BOOTROM_BUILD_DIR=$NANOSOC_TECH_DIR/system/src/bootrom TOOL_CHAIN=ds5
......@@ -92,9 +71,6 @@ build-job-ZCU104: # This job runs in the build stage, which runs first.
- echo "Build failed"
- exit 1
- fi
# cleanup arm-AAA-ip directory
- cd ../../../
- rm -r arm-AAA-ip
artifacts:
paths:
# Keep the generated bit and hwh file from fpga build script
......
//-----------------------------------------------------------------------------
// SoC Labs Basic Example Accelerator Wrapper
// 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 nanosoc_acc_wrapper #(
parameter AHBADDRWIDTH=16,
parameter INPACKETWIDTH=128,
parameter CFGSIZEWIDTH=64,
parameter CFGSCHEMEWIDTH=2,
parameter OUTPACKETWIDTH=128,
parameter CFGNUMIRQ=4
) (
input wire HCLK, // Clock
input wire HRESETn, // Reset
// AHB connection to Initiator
input wire HSELS,
input wire [AHBADDRWIDTH-1:0] HADDRS,
input wire [1:0] HTRANSS,
input wire [2:0] HSIZES,
input wire [3:0] HPROTS,
input wire HWRITES,
input wire HREADYS,
input wire [31:0] HWDATAS,
output wire HREADYOUTS,
output wire HRESPS,
output wire [31:0] HRDATAS,
// Input Data Request Signal to DMAC
output wire exp_drq_ip_o,
input wire exp_dlast_ip_i,
// Output Data Request Signal to DMAC
output wire exp_drq_op_o,
input wire exp_dlast_op_i,
// Interrupts
output wire [CFGNUMIRQ-1:0] exp_irq_o
);
soclabs_ahb_aes128_ctrl u_exp_aes128 (
.ahb_hclk (HCLK),
.ahb_hresetn (HRESETn),
.ahb_hsel (HSELS),
.ahb_haddr16 (HADDRS[15:0]),
.ahb_htrans (HTRANSS),
.ahb_hwrite (HWRITES),
.ahb_hsize (HSIZES),
.ahb_hprot (HPROTS),
.ahb_hwdata (HWDATAS),
.ahb_hready (HREADYS),
.ahb_hrdata (HRDATAS),
.ahb_hreadyout (HREADYOUTS),
.ahb_hresp (HRESPS),
.drq_ipdma128 (exp_drq_ip_o),
.dlast_ipdma128 (1'b0),
.drq_opdma128 (exp_drq_op_o),
.dlast_opdma128 (1'b0),
.irq_key128 (exp_irq_o[0]),
.irq_ip128 (exp_irq_o[1]),
.irq_op128 (exp_irq_o[2]),
.irq_error (exp_irq_o[3]),
.irq_merged ( )
);
endmodule
//-----------------------------------------------------------------------------
// SoC Labs Basic Example Accelerator Wrapper
// 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 nanosoc_exp_wrapper #(
parameter AHBADDRWIDTH=16,
parameter INPACKETWIDTH=128,
parameter CFGSIZEWIDTH=64,
parameter CFGSCHEMEWIDTH=2,
parameter OUTPACKETWIDTH=128,
parameter CFGNUMIRQ=4
) (
input wire HCLK, // Clock
input wire HRESETn, // Reset
// AHB connection to Initiator
input wire HSEL_i,
input wire [AHBADDRWIDTH-1:0] HADDR_i,
input wire [1:0] HTRANS_i,
input wire [2:0] HSIZE_i,
input wire [3:0] HPROT_i,
input wire HWRITE_i,
input wire HREADY_i,
input wire [31:0] HWDATA_i,
output wire HREADYOUT_o,
output wire HRESP_o,
output wire [31:0] HRDATA_o,
// Input Data Request Signal to DMAC
output wire exp_drq_ip_o,
input wire exp_dlast_ip_i,
// Output Data Request Signal to DMAC
output wire exp_drq_op_o,
input wire exp_dlast_op_i,
// Interrupts
output wire [CFGNUMIRQ-1:0] exp_irq_o
);
soclabs_ahb_aes128_ctrl u_exp_aes128 (
.ahb_hclk (HCLK),
.ahb_hresetn (HRESETn),
.ahb_hsel (HSEL_i),
.ahb_haddr16 (HADDR_i[15:0]),
.ahb_htrans (HTRANS_i),
.ahb_hwrite (HWRITE_i),
.ahb_hsize (HSIZE_i),
.ahb_hprot (HPROT_i),
.ahb_hwdata (HWDATA_i),
.ahb_hready (HREADY_i),
.ahb_hrdata (HRDATA_o),
.ahb_hreadyout (HREADYOUT_o),
.ahb_hresp (HRESP_o),
.drq_ipdma128 (exp_drq_ip_o),
.dlast_ipdma128 (1'b0),
.drq_opdma128 (exp_drq_op_o),
.dlast_opdma128 (1'b0),
.irq_key128 (exp_irq_o[0]),
.irq_ip128 (exp_irq_o[1]),
.irq_op128 (exp_irq_o[2]),
.irq_error (exp_irq_o[3]),
.irq_merged ( )
);
endmodule
......@@ -567,2449 +567,17 @@ module soclabs_iobuf_reg128
endmodule
//======================================================================
//
// aes_core.v
// ----------
// The AES core. This core supports key size of 128, and 256 bits.
// Most of the functionality is within the submodules.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2013, 2014, Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_core(
input wire clk,
input wire reset_n,
input wire encdec,
input wire init,
input wire next,
output wire ready,
input wire [255 : 0] key,
input wire keylen,
input wire [127 : 0] block,
output wire [127 : 0] result,
output wire result_valid
);
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
localparam CTRL_IDLE = 2'h0;
localparam CTRL_INIT = 2'h1;
localparam CTRL_NEXT = 2'h2;
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
reg [1 : 0] aes_core_ctrl_reg;
reg [1 : 0] aes_core_ctrl_new;
reg aes_core_ctrl_we;
reg result_valid_reg;
reg result_valid_new;
reg result_valid_we;
reg ready_reg;
reg ready_new;
reg ready_we;
//----------------------------------------------------------------
// Wires.
//----------------------------------------------------------------
reg init_state;
wire [127 : 0] round_key;
wire key_ready;
reg enc_next;
wire [3 : 0] enc_round_nr;
wire [127 : 0] enc_new_block;
wire enc_ready;
wire [31 : 0] enc_sboxw;
reg dec_next;
wire [3 : 0] dec_round_nr;
wire [127 : 0] dec_new_block;
wire dec_ready;
reg [127 : 0] muxed_new_block;
reg [3 : 0] muxed_round_nr;
reg muxed_ready;
wire [31 : 0] keymem_sboxw;
/* verilator lint_off UNOPTFLAT */
reg [31 : 0] muxed_sboxw;
wire [31 : 0] new_sboxw;
/* verilator lint_on UNOPTFLAT */
//----------------------------------------------------------------
// Instantiations.
//----------------------------------------------------------------
aes_encipher_block enc_block(
.clk(clk),
.reset_n(reset_n),
.next(enc_next),
.keylen(keylen),
.round(enc_round_nr),
.round_key(round_key),
.sboxw(enc_sboxw),
.new_sboxw(new_sboxw),
.block(block),
.new_block(enc_new_block),
.ready(enc_ready)
);
aes_decipher_block dec_block(
.clk(clk),
.reset_n(reset_n),
.next(dec_next),
.keylen(keylen),
.round(dec_round_nr),
.round_key(round_key),
.block(block),
.new_block(dec_new_block),
.ready(dec_ready)
);
aes_key_mem keymem(
.clk(clk),
.reset_n(reset_n),
.key(key),
.keylen(keylen),
.init(init),
.round(muxed_round_nr),
.round_key(round_key),
.ready(key_ready),
.sboxw(keymem_sboxw),
.new_sboxw(new_sboxw)
);
aes_sbox sbox_inst(.sboxw(muxed_sboxw), .new_sboxw(new_sboxw));
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
assign ready = ready_reg;
assign result = muxed_new_block;
assign result_valid = result_valid_reg;
//----------------------------------------------------------------
// reg_update
//
// Update functionality for all registers in the core.
// All registers are positive edge triggered with asynchronous
// active low reset. All registers have write enable.
//----------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
begin: reg_update
if (!reset_n)
begin
result_valid_reg <= 1'b0;
ready_reg <= 1'b1;
aes_core_ctrl_reg <= CTRL_IDLE;
end
else
begin
if (result_valid_we)
result_valid_reg <= result_valid_new;
if (ready_we)
ready_reg <= ready_new;
if (aes_core_ctrl_we)
aes_core_ctrl_reg <= aes_core_ctrl_new;
end
end // reg_update
//----------------------------------------------------------------
// sbox_mux
//
// Controls which of the encipher datapath or the key memory
// that gets access to the sbox.
//----------------------------------------------------------------
always @*
begin : sbox_mux
if (init_state)
begin
muxed_sboxw = keymem_sboxw;
end
else
begin
muxed_sboxw = enc_sboxw;
end
end // sbox_mux
//----------------------------------------------------------------
// encdex_mux
//
// Controls which of the datapaths that get the next signal, have
// access to the memory as well as the block processing result.
//----------------------------------------------------------------
always @*
begin : encdec_mux
enc_next = 1'b0;
dec_next = 1'b0;
if (encdec)
begin
// Encipher operations
enc_next = next;
muxed_round_nr = enc_round_nr;
muxed_new_block = enc_new_block;
muxed_ready = enc_ready;
end
else
begin
// Decipher operations
dec_next = next;
muxed_round_nr = dec_round_nr;
muxed_new_block = dec_new_block;
muxed_ready = dec_ready;
end
end // encdec_mux
//----------------------------------------------------------------
// aes_core_ctrl
//
// Control FSM for aes core. Basically tracks if we are in
// key init, encipher or decipher modes and connects the
// different submodules to shared resources and interface ports.
//----------------------------------------------------------------
always @*
begin : aes_core_ctrl
init_state = 1'b0;
ready_new = 1'b0;
ready_we = 1'b0;
result_valid_new = 1'b0;
result_valid_we = 1'b0;
aes_core_ctrl_new = CTRL_IDLE;
aes_core_ctrl_we = 1'b0;
case (aes_core_ctrl_reg)
CTRL_IDLE:
begin
if (init)
begin
init_state = 1'b1;
ready_new = 1'b0;
ready_we = 1'b1;
result_valid_new = 1'b0;
result_valid_we = 1'b1;
aes_core_ctrl_new = CTRL_INIT;
aes_core_ctrl_we = 1'b1;
end
else if (next)
begin
init_state = 1'b0;
ready_new = 1'b0;
ready_we = 1'b1;
result_valid_new = 1'b0;
result_valid_we = 1'b1;
aes_core_ctrl_new = CTRL_NEXT;
aes_core_ctrl_we = 1'b1;
end
end
CTRL_INIT:
begin
init_state = 1'b1;
if (key_ready)
begin
ready_new = 1'b1;
ready_we = 1'b1;
aes_core_ctrl_new = CTRL_IDLE;
aes_core_ctrl_we = 1'b1;
end
end
CTRL_NEXT:
begin
init_state = 1'b0;
if (muxed_ready)
begin
ready_new = 1'b1;
ready_we = 1'b1;
result_valid_new = 1'b1;
result_valid_we = 1'b1;
aes_core_ctrl_new = CTRL_IDLE;
aes_core_ctrl_we = 1'b1;
end
end
default:
begin
end
endcase // case (aes_core_ctrl_reg)
end // aes_core_ctrl
endmodule // aes_core
//======================================================================
// EOF aes_core.v
//======================================================================
//======================================================================
//
// aes_encipher_block.v
// --------------------
// The AES encipher round. A pure combinational module that implements
// the initial round, main round and final round logic for
// enciper operations.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2013, 2014, Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_encipher_block(
input wire clk,
input wire reset_n,
input wire next,
input wire keylen,
output wire [3 : 0] round,
input wire [127 : 0] round_key,
output wire [31 : 0] sboxw,
input wire [31 : 0] new_sboxw,
input wire [127 : 0] block,
output wire [127 : 0] new_block,
output wire ready
);
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
localparam AES_128_BIT_KEY = 1'h0;
localparam AES_256_BIT_KEY = 1'h1;
localparam AES128_ROUNDS = 4'ha;
localparam AES256_ROUNDS = 4'he;
localparam NO_UPDATE = 3'h0;
localparam INIT_UPDATE = 3'h1;
localparam SBOX_UPDATE = 3'h2;
localparam MAIN_UPDATE = 3'h3;
localparam FINAL_UPDATE = 3'h4;
localparam CTRL_IDLE = 2'h0;
localparam CTRL_INIT = 2'h1;
localparam CTRL_SBOX = 2'h2;
localparam CTRL_MAIN = 2'h3;
//----------------------------------------------------------------
// Round functions with sub functions.
//----------------------------------------------------------------
function [7 : 0] gm2(input [7 : 0] op);
begin
gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}});
end
endfunction // gm2
function [7 : 0] gm3(input [7 : 0] op);
begin
gm3 = gm2(op) ^ op;
end
endfunction // gm3
function [31 : 0] mixw(input [31 : 0] w);
reg [7 : 0] b0, b1, b2, b3;
reg [7 : 0] mb0, mb1, mb2, mb3;
begin
b0 = w[31 : 24];
b1 = w[23 : 16];
b2 = w[15 : 08];
b3 = w[07 : 00];
mb0 = gm2(b0) ^ gm3(b1) ^ b2 ^ b3;
mb1 = b0 ^ gm2(b1) ^ gm3(b2) ^ b3;
mb2 = b0 ^ b1 ^ gm2(b2) ^ gm3(b3);
mb3 = gm3(b0) ^ b1 ^ b2 ^ gm2(b3);
mixw = {mb0, mb1, mb2, mb3};
end
endfunction // mixw
function [127 : 0] mixcolumns(input [127 : 0] data);
reg [31 : 0] w0, w1, w2, w3;
reg [31 : 0] ws0, ws1, ws2, ws3;
begin
w0 = data[127 : 096];
w1 = data[095 : 064];
w2 = data[063 : 032];
w3 = data[031 : 000];
ws0 = mixw(w0);
ws1 = mixw(w1);
ws2 = mixw(w2);
ws3 = mixw(w3);
mixcolumns = {ws0, ws1, ws2, ws3};
end
endfunction // mixcolumns
function [127 : 0] shiftrows(input [127 : 0] data);
reg [31 : 0] w0, w1, w2, w3;
reg [31 : 0] ws0, ws1, ws2, ws3;
begin
w0 = data[127 : 096];
w1 = data[095 : 064];
w2 = data[063 : 032];
w3 = data[031 : 000];
ws0 = {w0[31 : 24], w1[23 : 16], w2[15 : 08], w3[07 : 00]};
ws1 = {w1[31 : 24], w2[23 : 16], w3[15 : 08], w0[07 : 00]};
ws2 = {w2[31 : 24], w3[23 : 16], w0[15 : 08], w1[07 : 00]};
ws3 = {w3[31 : 24], w0[23 : 16], w1[15 : 08], w2[07 : 00]};
shiftrows = {ws0, ws1, ws2, ws3};
end
endfunction // shiftrows
function [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey);
begin
addroundkey = data ^ rkey;
end
endfunction // addroundkey
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
reg [1 : 0] sword_ctr_reg;
reg [1 : 0] sword_ctr_new;
reg sword_ctr_we;
reg sword_ctr_inc;
reg sword_ctr_rst;
reg [3 : 0] round_ctr_reg;
reg [3 : 0] round_ctr_new;
reg round_ctr_we;
reg round_ctr_rst;
reg round_ctr_inc;
reg [127 : 0] block_new;
reg [31 : 0] block_w0_reg;
reg [31 : 0] block_w1_reg;
reg [31 : 0] block_w2_reg;
reg [31 : 0] block_w3_reg;
reg block_w0_we;
reg block_w1_we;
reg block_w2_we;
reg block_w3_we;
reg ready_reg;
reg ready_new;
reg ready_we;
reg [1 : 0] enc_ctrl_reg;
reg [1 : 0] enc_ctrl_new;
reg enc_ctrl_we;
//----------------------------------------------------------------
// Wires.
//----------------------------------------------------------------
reg [2 : 0] update_type;
reg [31 : 0] muxed_sboxw;
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
assign round = round_ctr_reg;
assign sboxw = muxed_sboxw;
assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
assign ready = ready_reg;
//----------------------------------------------------------------
// reg_update
//
// Update functionality for all registers in the core.
// All registers are positive edge triggered with asynchronous
// active low reset. All registers have write enable.
//----------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
begin: reg_update
if (!reset_n)
begin
block_w0_reg <= 32'h0;
block_w1_reg <= 32'h0;
block_w2_reg <= 32'h0;
block_w3_reg <= 32'h0;
sword_ctr_reg <= 2'h0;
round_ctr_reg <= 4'h0;
ready_reg <= 1'b1;
enc_ctrl_reg <= CTRL_IDLE;
end
else
begin
if (block_w0_we)
block_w0_reg <= block_new[127 : 096];
if (block_w1_we)
block_w1_reg <= block_new[095 : 064];
if (block_w2_we)
block_w2_reg <= block_new[063 : 032];
if (block_w3_we)
block_w3_reg <= block_new[031 : 000];
if (sword_ctr_we)
sword_ctr_reg <= sword_ctr_new;
if (round_ctr_we)
round_ctr_reg <= round_ctr_new;
if (ready_we)
ready_reg <= ready_new;
if (enc_ctrl_we)
enc_ctrl_reg <= enc_ctrl_new;
end
end // reg_update
//----------------------------------------------------------------
// round_logic
//
// The logic needed to implement init, main and final rounds.
//----------------------------------------------------------------
always @*
begin : round_logic
reg [127 : 0] old_block, shiftrows_block, mixcolumns_block;
reg [127 : 0] addkey_init_block, addkey_main_block, addkey_final_block;
block_new = 128'h0;
muxed_sboxw = 32'h0;
block_w0_we = 1'b0;
block_w1_we = 1'b0;
block_w2_we = 1'b0;
block_w3_we = 1'b0;
old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
shiftrows_block = shiftrows(old_block);
mixcolumns_block = mixcolumns(shiftrows_block);
addkey_init_block = addroundkey(block, round_key);
addkey_main_block = addroundkey(mixcolumns_block, round_key);
addkey_final_block = addroundkey(shiftrows_block, round_key);
case (update_type)
INIT_UPDATE:
begin
block_new = addkey_init_block;
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
SBOX_UPDATE:
begin
block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw};
case (sword_ctr_reg)
2'h0:
begin
muxed_sboxw = block_w0_reg;
block_w0_we = 1'b1;
end
2'h1:
begin
muxed_sboxw = block_w1_reg;
block_w1_we = 1'b1;
end
2'h2:
begin
muxed_sboxw = block_w2_reg;
block_w2_we = 1'b1;
end
2'h3:
begin
muxed_sboxw = block_w3_reg;
block_w3_we = 1'b1;
end
endcase // case (sbox_mux_ctrl_reg)
end
MAIN_UPDATE:
begin
block_new = addkey_main_block;
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
FINAL_UPDATE:
begin
block_new = addkey_final_block;
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
default:
begin
end
endcase // case (update_type)
end // round_logic
//----------------------------------------------------------------
// sword_ctr
//
// The subbytes word counter with reset and increase logic.
//----------------------------------------------------------------
always @*
begin : sword_ctr
sword_ctr_new = 2'h0;
sword_ctr_we = 1'b0;
if (sword_ctr_rst)
begin
sword_ctr_new = 2'h0;
sword_ctr_we = 1'b1;
end
else if (sword_ctr_inc)
begin
sword_ctr_new = sword_ctr_reg + 1'b1;
sword_ctr_we = 1'b1;
end
end // sword_ctr
//----------------------------------------------------------------
// round_ctr
//
// The round counter with reset and increase logic.
//----------------------------------------------------------------
always @*
begin : round_ctr
round_ctr_new = 4'h0;
round_ctr_we = 1'b0;
if (round_ctr_rst)
begin
round_ctr_new = 4'h0;
round_ctr_we = 1'b1;
end
else if (round_ctr_inc)
begin
round_ctr_new = round_ctr_reg + 1'b1;
round_ctr_we = 1'b1;
end
end // round_ctr
//----------------------------------------------------------------
// encipher_ctrl
//
// The FSM that controls the encipher operations.
//----------------------------------------------------------------
always @*
begin: encipher_ctrl
reg [3 : 0] num_rounds;
// Default assignments.
sword_ctr_inc = 1'b0;
sword_ctr_rst = 1'b0;
round_ctr_inc = 1'b0;
round_ctr_rst = 1'b0;
ready_new = 1'b0;
ready_we = 1'b0;
update_type = NO_UPDATE;
enc_ctrl_new = CTRL_IDLE;
enc_ctrl_we = 1'b0;
if (keylen == AES_256_BIT_KEY)
begin
num_rounds = AES256_ROUNDS;
end
else
begin
num_rounds = AES128_ROUNDS;
end
case(enc_ctrl_reg)
CTRL_IDLE:
begin
if (next)
begin
round_ctr_rst = 1'b1;
ready_new = 1'b0;
ready_we = 1'b1;
enc_ctrl_new = CTRL_INIT;
enc_ctrl_we = 1'b1;
end
end
CTRL_INIT:
begin
round_ctr_inc = 1'b1;
sword_ctr_rst = 1'b1;
update_type = INIT_UPDATE;
enc_ctrl_new = CTRL_SBOX;
enc_ctrl_we = 1'b1;
end
CTRL_SBOX:
begin
sword_ctr_inc = 1'b1;
update_type = SBOX_UPDATE;
if (sword_ctr_reg == 2'h3)
begin
enc_ctrl_new = CTRL_MAIN;
enc_ctrl_we = 1'b1;
end
end
CTRL_MAIN:
begin
sword_ctr_rst = 1'b1;
round_ctr_inc = 1'b1;
if (round_ctr_reg < num_rounds)
begin
update_type = MAIN_UPDATE;
enc_ctrl_new = CTRL_SBOX;
enc_ctrl_we = 1'b1;
end
else
begin
update_type = FINAL_UPDATE;
ready_new = 1'b1;
ready_we = 1'b1;
enc_ctrl_new = CTRL_IDLE;
enc_ctrl_we = 1'b1;
end
end
default:
begin
// Empty. Just here to make the synthesis tool happy.
end
endcase // case (enc_ctrl_reg)
end // encipher_ctrl
endmodule // aes_encipher_block
//======================================================================
// EOF aes_encipher_block.v
//======================================================================
//======================================================================
//
// aes_decipher_block.v
// --------------------
// The AES decipher round. A pure combinational module that implements
// the initial round, main round and final round logic for
// decciper operations.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2013, 2014, Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_decipher_block(
input wire clk,
input wire reset_n,
input wire next,
input wire keylen,
output wire [3 : 0] round,
input wire [127 : 0] round_key,
input wire [127 : 0] block,
output wire [127 : 0] new_block,
output wire ready
);
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
localparam AES_128_BIT_KEY = 1'h0;
localparam AES_256_BIT_KEY = 1'h1;
localparam AES128_ROUNDS = 4'ha;
localparam AES256_ROUNDS = 4'he;
localparam NO_UPDATE = 3'h0;
localparam INIT_UPDATE = 3'h1;
localparam SBOX_UPDATE = 3'h2;
localparam MAIN_UPDATE = 3'h3;
localparam FINAL_UPDATE = 3'h4;
localparam CTRL_IDLE = 2'h0;
localparam CTRL_INIT = 2'h1;
localparam CTRL_SBOX = 2'h2;
localparam CTRL_MAIN = 2'h3;
//----------------------------------------------------------------
// Gaolis multiplication functions for Inverse MixColumn.
//----------------------------------------------------------------
function [7 : 0] gm2(input [7 : 0] op);
begin
gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}});
end
endfunction // gm2
function [7 : 0] gm3(input [7 : 0] op);
begin
gm3 = gm2(op) ^ op;
end
endfunction // gm3
function [7 : 0] gm4(input [7 : 0] op);
begin
gm4 = gm2(gm2(op));
end
endfunction // gm4
function [7 : 0] gm8(input [7 : 0] op);
begin
gm8 = gm2(gm4(op));
end
endfunction // gm8
function [7 : 0] gm09(input [7 : 0] op);
begin
gm09 = gm8(op) ^ op;
end
endfunction // gm09
function [7 : 0] gm11(input [7 : 0] op);
begin
gm11 = gm8(op) ^ gm2(op) ^ op;
end
endfunction // gm11
function [7 : 0] gm13(input [7 : 0] op);
begin
gm13 = gm8(op) ^ gm4(op) ^ op;
end
endfunction // gm13
function [7 : 0] gm14(input [7 : 0] op);
begin
gm14 = gm8(op) ^ gm4(op) ^ gm2(op);
end
endfunction // gm14
function [31 : 0] inv_mixw(input [31 : 0] w);
reg [7 : 0] b0, b1, b2, b3;
reg [7 : 0] mb0, mb1, mb2, mb3;
begin
b0 = w[31 : 24];
b1 = w[23 : 16];
b2 = w[15 : 08];
b3 = w[07 : 00];
mb0 = gm14(b0) ^ gm11(b1) ^ gm13(b2) ^ gm09(b3);
mb1 = gm09(b0) ^ gm14(b1) ^ gm11(b2) ^ gm13(b3);
mb2 = gm13(b0) ^ gm09(b1) ^ gm14(b2) ^ gm11(b3);
mb3 = gm11(b0) ^ gm13(b1) ^ gm09(b2) ^ gm14(b3);
inv_mixw = {mb0, mb1, mb2, mb3};
end
endfunction // mixw
function [127 : 0] inv_mixcolumns(input [127 : 0] data);
reg [31 : 0] w0, w1, w2, w3;
reg [31 : 0] ws0, ws1, ws2, ws3;
begin
w0 = data[127 : 096];
w1 = data[095 : 064];
w2 = data[063 : 032];
w3 = data[031 : 000];
ws0 = inv_mixw(w0);
ws1 = inv_mixw(w1);
ws2 = inv_mixw(w2);
ws3 = inv_mixw(w3);
inv_mixcolumns = {ws0, ws1, ws2, ws3};
end
endfunction // inv_mixcolumns
function [127 : 0] inv_shiftrows(input [127 : 0] data);
reg [31 : 0] w0, w1, w2, w3;
reg [31 : 0] ws0, ws1, ws2, ws3;
begin
w0 = data[127 : 096];
w1 = data[095 : 064];
w2 = data[063 : 032];
w3 = data[031 : 000];
ws0 = {w0[31 : 24], w3[23 : 16], w2[15 : 08], w1[07 : 00]};
ws1 = {w1[31 : 24], w0[23 : 16], w3[15 : 08], w2[07 : 00]};
ws2 = {w2[31 : 24], w1[23 : 16], w0[15 : 08], w3[07 : 00]};
ws3 = {w3[31 : 24], w2[23 : 16], w1[15 : 08], w0[07 : 00]};
inv_shiftrows = {ws0, ws1, ws2, ws3};
end
endfunction // inv_shiftrows
function [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey);
begin
addroundkey = data ^ rkey;
end
endfunction // addroundkey
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
reg [1 : 0] sword_ctr_reg;
reg [1 : 0] sword_ctr_new;
reg sword_ctr_we;
reg sword_ctr_inc;
reg sword_ctr_rst;
reg [3 : 0] round_ctr_reg;
reg [3 : 0] round_ctr_new;
reg round_ctr_we;
reg round_ctr_set;
reg round_ctr_dec;
reg [127 : 0] block_new;
reg [31 : 0] block_w0_reg;
reg [31 : 0] block_w1_reg;
reg [31 : 0] block_w2_reg;
reg [31 : 0] block_w3_reg;
reg block_w0_we;
reg block_w1_we;
reg block_w2_we;
reg block_w3_we;
reg ready_reg;
reg ready_new;
reg ready_we;
reg [1 : 0] dec_ctrl_reg;
reg [1 : 0] dec_ctrl_new;
reg dec_ctrl_we;
//----------------------------------------------------------------
// Wires.
//----------------------------------------------------------------
reg [31 : 0] tmp_sboxw;
wire [31 : 0] new_sboxw;
reg [2 : 0] update_type;
//----------------------------------------------------------------
// Instantiations.
//----------------------------------------------------------------
aes_inv_sbox inv_sbox_inst(.sboxw(tmp_sboxw), .new_sboxw(new_sboxw));
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
assign round = round_ctr_reg;
assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
assign ready = ready_reg;
//----------------------------------------------------------------
// reg_update
//
// Update functionality for all registers in the core.
// All registers are positive edge triggered with synchronous
// active low reset. All registers have write enable.
//----------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
begin: reg_update
if (!reset_n)
begin
block_w0_reg <= 32'h0;
block_w1_reg <= 32'h0;
block_w2_reg <= 32'h0;
block_w3_reg <= 32'h0;
sword_ctr_reg <= 2'h0;
round_ctr_reg <= 4'h0;
ready_reg <= 1'b1;
dec_ctrl_reg <= CTRL_IDLE;
end
else
begin
if (block_w0_we)
block_w0_reg <= block_new[127 : 096];
if (block_w1_we)
block_w1_reg <= block_new[095 : 064];
if (block_w2_we)
block_w2_reg <= block_new[063 : 032];
if (block_w3_we)
block_w3_reg <= block_new[031 : 000];
if (sword_ctr_we)
sword_ctr_reg <= sword_ctr_new;
if (round_ctr_we)
round_ctr_reg <= round_ctr_new;
if (ready_we)
ready_reg <= ready_new;
if (dec_ctrl_we)
dec_ctrl_reg <= dec_ctrl_new;
end
end // reg_update
//----------------------------------------------------------------
// round_logic
//
// The logic needed to implement init, main and final rounds.
//----------------------------------------------------------------
always @*
begin : round_logic
reg [127 : 0] old_block, inv_shiftrows_block, inv_mixcolumns_block;
reg [127 : 0] addkey_block;
inv_shiftrows_block = 128'h0;
inv_mixcolumns_block = 128'h0;
addkey_block = 128'h0;
block_new = 128'h0;
tmp_sboxw = 32'h0;
block_w0_we = 1'b0;
block_w1_we = 1'b0;
block_w2_we = 1'b0;
block_w3_we = 1'b0;
old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
// Update based on update type.
case (update_type)
// InitRound
INIT_UPDATE:
begin
old_block = block;
addkey_block = addroundkey(old_block, round_key);
inv_shiftrows_block = inv_shiftrows(addkey_block);
block_new = inv_shiftrows_block;
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
SBOX_UPDATE:
begin
block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw};
case (sword_ctr_reg)
2'h0:
begin
tmp_sboxw = block_w0_reg;
block_w0_we = 1'b1;
end
2'h1:
begin
tmp_sboxw = block_w1_reg;
block_w1_we = 1'b1;
end
2'h2:
begin
tmp_sboxw = block_w2_reg;
block_w2_we = 1'b1;
end
2'h3:
begin
tmp_sboxw = block_w3_reg;
block_w3_we = 1'b1;
end
endcase // case (sbox_mux_ctrl_reg)
end
MAIN_UPDATE:
begin
addkey_block = addroundkey(old_block, round_key);
inv_mixcolumns_block = inv_mixcolumns(addkey_block);
inv_shiftrows_block = inv_shiftrows(inv_mixcolumns_block);
block_new = inv_shiftrows_block;
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
FINAL_UPDATE:
begin
block_new = addroundkey(old_block, round_key);
block_w0_we = 1'b1;
block_w1_we = 1'b1;
block_w2_we = 1'b1;
block_w3_we = 1'b1;
end
default:
begin
end
endcase // case (update_type)
end // round_logic
//----------------------------------------------------------------
// sword_ctr
//
// The subbytes word counter with reset and increase logic.
//----------------------------------------------------------------
always @*
begin : sword_ctr
sword_ctr_new = 2'h0;
sword_ctr_we = 1'b0;
if (sword_ctr_rst)
begin
sword_ctr_new = 2'h0;
sword_ctr_we = 1'b1;
end
else if (sword_ctr_inc)
begin
sword_ctr_new = sword_ctr_reg + 1'b1;
sword_ctr_we = 1'b1;
end
end // sword_ctr
//----------------------------------------------------------------
// round_ctr
//
// The round counter with reset and increase logic.
//----------------------------------------------------------------
always @*
begin : round_ctr
round_ctr_new = 4'h0;
round_ctr_we = 1'b0;
if (round_ctr_set)
begin
if (keylen == AES_256_BIT_KEY)
begin
round_ctr_new = AES256_ROUNDS;
end
else
begin
round_ctr_new = AES128_ROUNDS;
end
round_ctr_we = 1'b1;
end
else if (round_ctr_dec)
begin
round_ctr_new = round_ctr_reg - 1'b1;
round_ctr_we = 1'b1;
end
end // round_ctr
//----------------------------------------------------------------
// decipher_ctrl
//
// The FSM that controls the decipher operations.
//----------------------------------------------------------------
always @*
begin: decipher_ctrl
sword_ctr_inc = 1'b0;
sword_ctr_rst = 1'b0;
round_ctr_dec = 1'b0;
round_ctr_set = 1'b0;
ready_new = 1'b0;
ready_we = 1'b0;
update_type = NO_UPDATE;
dec_ctrl_new = CTRL_IDLE;
dec_ctrl_we = 1'b0;
case(dec_ctrl_reg)
CTRL_IDLE:
begin
if (next)
begin
round_ctr_set = 1'b1;
ready_new = 1'b0;
ready_we = 1'b1;
dec_ctrl_new = CTRL_INIT;
dec_ctrl_we = 1'b1;
end
end
CTRL_INIT:
begin
sword_ctr_rst = 1'b1;
update_type = INIT_UPDATE;
dec_ctrl_new = CTRL_SBOX;
dec_ctrl_we = 1'b1;
end
CTRL_SBOX:
begin
sword_ctr_inc = 1'b1;
update_type = SBOX_UPDATE;
if (sword_ctr_reg == 2'h3)
begin
round_ctr_dec = 1'b1;
dec_ctrl_new = CTRL_MAIN;
dec_ctrl_we = 1'b1;
end
end
CTRL_MAIN:
begin
sword_ctr_rst = 1'b1;
if (round_ctr_reg > 0)
begin
update_type = MAIN_UPDATE;
dec_ctrl_new = CTRL_SBOX;
dec_ctrl_we = 1'b1;
end
else
begin
update_type = FINAL_UPDATE;
ready_new = 1'b1;
ready_we = 1'b1;
dec_ctrl_new = CTRL_IDLE;
dec_ctrl_we = 1'b1;
end
end
default:
begin
// Empty. Just here to make the synthesis tool happy.
end
endcase // case (dec_ctrl_reg)
end // decipher_ctrl
endmodule // aes_decipher_block
//======================================================================
// EOF aes_decipher_block.v
//======================================================================
//======================================================================
//
// aes_key_mem.v
// -------------
// The AES key memory including round key generator.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2013 Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_key_mem(
input wire clk,
input wire reset_n,
input wire [255 : 0] key,
input wire keylen,
input wire init,
input wire [3 : 0] round,
output wire [127 : 0] round_key,
output wire ready,
output wire [31 : 0] sboxw,
input wire [31 : 0] new_sboxw
);
//----------------------------------------------------------------
// Parameters.
//----------------------------------------------------------------
localparam AES_128_BIT_KEY = 1'h0;
localparam AES_256_BIT_KEY = 1'h1;
localparam AES_128_NUM_ROUNDS = 10;
localparam AES_256_NUM_ROUNDS = 14;
localparam CTRL_IDLE = 3'h0;
localparam CTRL_INIT = 3'h1;
localparam CTRL_GENERATE = 3'h2;
localparam CTRL_DONE = 3'h3;
//----------------------------------------------------------------
// Registers.
//----------------------------------------------------------------
reg [127 : 0] key_mem [0 : 14];
reg [127 : 0] key_mem_new;
reg key_mem_we;
reg [127 : 0] prev_key0_reg;
reg [127 : 0] prev_key0_new;
reg prev_key0_we;
reg [127 : 0] prev_key1_reg;
reg [127 : 0] prev_key1_new;
reg prev_key1_we;
reg [3 : 0] round_ctr_reg;
reg [3 : 0] round_ctr_new;
reg round_ctr_rst;
reg round_ctr_inc;
reg round_ctr_we;
reg [2 : 0] key_mem_ctrl_reg;
reg [2 : 0] key_mem_ctrl_new;
reg key_mem_ctrl_we;
reg ready_reg;
reg ready_new;
reg ready_we;
reg [7 : 0] rcon_reg;
reg [7 : 0] rcon_new;
reg rcon_we;
reg rcon_set;
reg rcon_next;
//----------------------------------------------------------------
// Wires.
//----------------------------------------------------------------
reg [31 : 0] tmp_sboxw;
reg round_key_update;
reg [127 : 0] tmp_round_key;
//----------------------------------------------------------------
// Concurrent assignments for ports.
//----------------------------------------------------------------
assign round_key = tmp_round_key;
assign ready = ready_reg;
assign sboxw = tmp_sboxw;
//----------------------------------------------------------------
// reg_update
//
// Update functionality for all registers in the core.
// All registers are positive edge triggered with asynchronous
// active low reset. All registers have write enable.
//----------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
begin: reg_update
integer i;
if (!reset_n)
begin
for (i = 0 ; i <= AES_256_NUM_ROUNDS ; i = i + 1)
key_mem [i] <= 128'h0;
ready_reg <= 1'b0;
rcon_reg <= 8'h0;
round_ctr_reg <= 4'h0;
prev_key0_reg <= 128'h0;
prev_key1_reg <= 128'h0;
key_mem_ctrl_reg <= CTRL_IDLE;
end
else
begin
if (ready_we)
ready_reg <= ready_new;
if (rcon_we)
rcon_reg <= rcon_new;
if (round_ctr_we)
round_ctr_reg <= round_ctr_new;
if (key_mem_we)
key_mem[round_ctr_reg] <= key_mem_new;
if (prev_key0_we)
prev_key0_reg <= prev_key0_new;
if (prev_key1_we)
prev_key1_reg <= prev_key1_new;
if (key_mem_ctrl_we)
key_mem_ctrl_reg <= key_mem_ctrl_new;
end
end // reg_update
//----------------------------------------------------------------
// key_mem_read
//
// Combinational read port for the key memory.
//----------------------------------------------------------------
always @*
begin : key_mem_read
tmp_round_key = key_mem[round];
end // key_mem_read
//----------------------------------------------------------------
// round_key_gen
//
// The round key generator logic for AES-128 and AES-256.
//----------------------------------------------------------------
always @*
begin: round_key_gen
reg [31 : 0] w0, w1, w2, w3, w4, w5, w6, w7;
reg [31 : 0] k0, k1, k2, k3;
reg [31 : 0] rconw, rotstw, tw, trw;
// Default assignments.
key_mem_new = 128'h0;
key_mem_we = 1'b0;
prev_key0_new = 128'h0;
prev_key0_we = 1'b0;
prev_key1_new = 128'h0;
prev_key1_we = 1'b0;
k0 = 32'h0;
k1 = 32'h0;
k2 = 32'h0;
k3 = 32'h0;
rcon_set = 1'b1;
rcon_next = 1'b0;
// Extract words and calculate intermediate values.
// Perform rotation of sbox word etc.
w0 = prev_key0_reg[127 : 096];
w1 = prev_key0_reg[095 : 064];
w2 = prev_key0_reg[063 : 032];
w3 = prev_key0_reg[031 : 000];
w4 = prev_key1_reg[127 : 096];
w5 = prev_key1_reg[095 : 064];
w6 = prev_key1_reg[063 : 032];
w7 = prev_key1_reg[031 : 000];
rconw = {rcon_reg, 24'h0};
tmp_sboxw = w7;
rotstw = {new_sboxw[23 : 00], new_sboxw[31 : 24]};
trw = rotstw ^ rconw;
tw = new_sboxw;
// Generate the specific round keys.
if (round_key_update)
begin
rcon_set = 1'b0;
key_mem_we = 1'b1;
case (keylen)
AES_128_BIT_KEY:
begin
if (round_ctr_reg == 0)
begin
key_mem_new = key[255 : 128];
prev_key1_new = key[255 : 128];
prev_key1_we = 1'b1;
rcon_next = 1'b1;
end
else
begin
k0 = w4 ^ trw;
k1 = w5 ^ w4 ^ trw;
k2 = w6 ^ w5 ^ w4 ^ trw;
k3 = w7 ^ w6 ^ w5 ^ w4 ^ trw;
key_mem_new = {k0, k1, k2, k3};
prev_key1_new = {k0, k1, k2, k3};
prev_key1_we = 1'b1;
rcon_next = 1'b1;
end
end
AES_256_BIT_KEY:
begin
if (round_ctr_reg == 0)
begin
key_mem_new = key[255 : 128];
prev_key0_new = key[255 : 128];
prev_key0_we = 1'b1;
end
else if (round_ctr_reg == 1)
begin
key_mem_new = key[127 : 0];
prev_key1_new = key[127 : 0];
prev_key1_we = 1'b1;
rcon_next = 1'b1;
end
else
begin
if (round_ctr_reg[0] == 0)
begin
k0 = w0 ^ trw;
k1 = w1 ^ w0 ^ trw;
k2 = w2 ^ w1 ^ w0 ^ trw;
k3 = w3 ^ w2 ^ w1 ^ w0 ^ trw;
end
else
begin
k0 = w0 ^ tw;
k1 = w1 ^ w0 ^ tw;
k2 = w2 ^ w1 ^ w0 ^ tw;
k3 = w3 ^ w2 ^ w1 ^ w0 ^ tw;
rcon_next = 1'b1;
end
// Store the generated round keys.
key_mem_new = {k0, k1, k2, k3};
prev_key1_new = {k0, k1, k2, k3};
prev_key1_we = 1'b1;
prev_key0_new = prev_key1_reg;
prev_key0_we = 1'b1;
end
end
default:
begin
end
endcase // case (keylen)
end
end // round_key_gen
//----------------------------------------------------------------
// rcon_logic
//
// Caclulates the rcon value for the different key expansion
// iterations.
//----------------------------------------------------------------
always @*
begin : rcon_logic
reg [7 : 0] tmp_rcon;
rcon_new = 8'h00;
rcon_we = 1'b0;
tmp_rcon = {rcon_reg[6 : 0], 1'b0} ^ (8'h1b & {8{rcon_reg[7]}});
if (rcon_set)
begin
rcon_new = 8'h8d;
rcon_we = 1'b1;
end
if (rcon_next)
begin
rcon_new = tmp_rcon[7 : 0];
rcon_we = 1'b1;
end
end
//----------------------------------------------------------------
// round_ctr
//
// The round counter logic with increase and reset.
//----------------------------------------------------------------
always @*
begin : round_ctr
round_ctr_new = 4'h0;
round_ctr_we = 1'b0;
if (round_ctr_rst)
begin
round_ctr_new = 4'h0;
round_ctr_we = 1'b1;
end
else if (round_ctr_inc)
begin
round_ctr_new = round_ctr_reg + 1'b1;
round_ctr_we = 1'b1;
end
end
//----------------------------------------------------------------
// key_mem_ctrl
//
//
// The FSM that controls the round key generation.
//----------------------------------------------------------------
always @*
begin: key_mem_ctrl
reg [3 : 0] num_rounds;
// Default assignments.
ready_new = 1'b0;
ready_we = 1'b0;
round_key_update = 1'b0;
round_ctr_rst = 1'b0;
round_ctr_inc = 1'b0;
key_mem_ctrl_new = CTRL_IDLE;
key_mem_ctrl_we = 1'b0;
if (keylen == AES_128_BIT_KEY)
num_rounds = AES_128_NUM_ROUNDS;
else
num_rounds = AES_256_NUM_ROUNDS;
case(key_mem_ctrl_reg)
CTRL_IDLE:
begin
if (init)
begin
ready_new = 1'b0;
ready_we = 1'b1;
key_mem_ctrl_new = CTRL_INIT;
key_mem_ctrl_we = 1'b1;
end
end
CTRL_INIT:
begin
round_ctr_rst = 1'b1;
key_mem_ctrl_new = CTRL_GENERATE;
key_mem_ctrl_we = 1'b1;
end
CTRL_GENERATE:
begin
round_ctr_inc = 1'b1;
round_key_update = 1'b1;
if (round_ctr_reg == num_rounds)
begin
key_mem_ctrl_new = CTRL_DONE;
key_mem_ctrl_we = 1'b1;
end
end
CTRL_DONE:
begin
ready_new = 1'b1;
ready_we = 1'b1;
key_mem_ctrl_new = CTRL_IDLE;
key_mem_ctrl_we = 1'b1;
end
default:
begin
end
endcase // case (key_mem_ctrl_reg)
end // key_mem_ctrl
endmodule // aes_key_mem
//======================================================================
// EOF aes_key_mem.v
//======================================================================
//======================================================================
//
// aes_sbox.v
// ----------
// The AES S-box. Basically a 256 Byte ROM. This implementation
// contains four parallel S-boxes to handle a 32 bit word.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_sbox(
input wire [31 : 0] sboxw,
output wire [31 : 0] new_sboxw
);
//----------------------------------------------------------------
// The sbox array.
//----------------------------------------------------------------
wire [7 : 0] sbox [0 : 255];
//----------------------------------------------------------------
// Four parallel muxes.
//----------------------------------------------------------------
assign new_sboxw[31 : 24] = sbox[sboxw[31 : 24]];
assign new_sboxw[23 : 16] = sbox[sboxw[23 : 16]];
assign new_sboxw[15 : 08] = sbox[sboxw[15 : 08]];
assign new_sboxw[07 : 00] = sbox[sboxw[07 : 00]];
//----------------------------------------------------------------
// Creating the sbox array contents.
//----------------------------------------------------------------
assign sbox[8'h00] = 8'h63;
assign sbox[8'h01] = 8'h7c;
assign sbox[8'h02] = 8'h77;
assign sbox[8'h03] = 8'h7b;
assign sbox[8'h04] = 8'hf2;
assign sbox[8'h05] = 8'h6b;
assign sbox[8'h06] = 8'h6f;
assign sbox[8'h07] = 8'hc5;
assign sbox[8'h08] = 8'h30;
assign sbox[8'h09] = 8'h01;
assign sbox[8'h0a] = 8'h67;
assign sbox[8'h0b] = 8'h2b;
assign sbox[8'h0c] = 8'hfe;
assign sbox[8'h0d] = 8'hd7;
assign sbox[8'h0e] = 8'hab;
assign sbox[8'h0f] = 8'h76;
assign sbox[8'h10] = 8'hca;
assign sbox[8'h11] = 8'h82;
assign sbox[8'h12] = 8'hc9;
assign sbox[8'h13] = 8'h7d;
assign sbox[8'h14] = 8'hfa;
assign sbox[8'h15] = 8'h59;
assign sbox[8'h16] = 8'h47;
assign sbox[8'h17] = 8'hf0;
assign sbox[8'h18] = 8'had;
assign sbox[8'h19] = 8'hd4;
assign sbox[8'h1a] = 8'ha2;
assign sbox[8'h1b] = 8'haf;
assign sbox[8'h1c] = 8'h9c;
assign sbox[8'h1d] = 8'ha4;
assign sbox[8'h1e] = 8'h72;
assign sbox[8'h1f] = 8'hc0;
assign sbox[8'h20] = 8'hb7;
assign sbox[8'h21] = 8'hfd;
assign sbox[8'h22] = 8'h93;
assign sbox[8'h23] = 8'h26;
assign sbox[8'h24] = 8'h36;
assign sbox[8'h25] = 8'h3f;
assign sbox[8'h26] = 8'hf7;
assign sbox[8'h27] = 8'hcc;
assign sbox[8'h28] = 8'h34;
assign sbox[8'h29] = 8'ha5;
assign sbox[8'h2a] = 8'he5;
assign sbox[8'h2b] = 8'hf1;
assign sbox[8'h2c] = 8'h71;
assign sbox[8'h2d] = 8'hd8;
assign sbox[8'h2e] = 8'h31;
assign sbox[8'h2f] = 8'h15;
assign sbox[8'h30] = 8'h04;
assign sbox[8'h31] = 8'hc7;
assign sbox[8'h32] = 8'h23;
assign sbox[8'h33] = 8'hc3;
assign sbox[8'h34] = 8'h18;
assign sbox[8'h35] = 8'h96;
assign sbox[8'h36] = 8'h05;
assign sbox[8'h37] = 8'h9a;
assign sbox[8'h38] = 8'h07;
assign sbox[8'h39] = 8'h12;
assign sbox[8'h3a] = 8'h80;
assign sbox[8'h3b] = 8'he2;
assign sbox[8'h3c] = 8'heb;
assign sbox[8'h3d] = 8'h27;
assign sbox[8'h3e] = 8'hb2;
assign sbox[8'h3f] = 8'h75;
assign sbox[8'h40] = 8'h09;
assign sbox[8'h41] = 8'h83;
assign sbox[8'h42] = 8'h2c;
assign sbox[8'h43] = 8'h1a;
assign sbox[8'h44] = 8'h1b;
assign sbox[8'h45] = 8'h6e;
assign sbox[8'h46] = 8'h5a;
assign sbox[8'h47] = 8'ha0;
assign sbox[8'h48] = 8'h52;
assign sbox[8'h49] = 8'h3b;
assign sbox[8'h4a] = 8'hd6;
assign sbox[8'h4b] = 8'hb3;
assign sbox[8'h4c] = 8'h29;
assign sbox[8'h4d] = 8'he3;
assign sbox[8'h4e] = 8'h2f;
assign sbox[8'h4f] = 8'h84;
assign sbox[8'h50] = 8'h53;
assign sbox[8'h51] = 8'hd1;
assign sbox[8'h52] = 8'h00;
assign sbox[8'h53] = 8'hed;
assign sbox[8'h54] = 8'h20;
assign sbox[8'h55] = 8'hfc;
assign sbox[8'h56] = 8'hb1;
assign sbox[8'h57] = 8'h5b;
assign sbox[8'h58] = 8'h6a;
assign sbox[8'h59] = 8'hcb;
assign sbox[8'h5a] = 8'hbe;
assign sbox[8'h5b] = 8'h39;
assign sbox[8'h5c] = 8'h4a;
assign sbox[8'h5d] = 8'h4c;
assign sbox[8'h5e] = 8'h58;
assign sbox[8'h5f] = 8'hcf;
assign sbox[8'h60] = 8'hd0;
assign sbox[8'h61] = 8'hef;
assign sbox[8'h62] = 8'haa;
assign sbox[8'h63] = 8'hfb;
assign sbox[8'h64] = 8'h43;
assign sbox[8'h65] = 8'h4d;
assign sbox[8'h66] = 8'h33;
assign sbox[8'h67] = 8'h85;
assign sbox[8'h68] = 8'h45;
assign sbox[8'h69] = 8'hf9;
assign sbox[8'h6a] = 8'h02;
assign sbox[8'h6b] = 8'h7f;
assign sbox[8'h6c] = 8'h50;
assign sbox[8'h6d] = 8'h3c;
assign sbox[8'h6e] = 8'h9f;
assign sbox[8'h6f] = 8'ha8;
assign sbox[8'h70] = 8'h51;
assign sbox[8'h71] = 8'ha3;
assign sbox[8'h72] = 8'h40;
assign sbox[8'h73] = 8'h8f;
assign sbox[8'h74] = 8'h92;
assign sbox[8'h75] = 8'h9d;
assign sbox[8'h76] = 8'h38;
assign sbox[8'h77] = 8'hf5;
assign sbox[8'h78] = 8'hbc;
assign sbox[8'h79] = 8'hb6;
assign sbox[8'h7a] = 8'hda;
assign sbox[8'h7b] = 8'h21;
assign sbox[8'h7c] = 8'h10;
assign sbox[8'h7d] = 8'hff;
assign sbox[8'h7e] = 8'hf3;
assign sbox[8'h7f] = 8'hd2;
assign sbox[8'h80] = 8'hcd;
assign sbox[8'h81] = 8'h0c;
assign sbox[8'h82] = 8'h13;
assign sbox[8'h83] = 8'hec;
assign sbox[8'h84] = 8'h5f;
assign sbox[8'h85] = 8'h97;
assign sbox[8'h86] = 8'h44;
assign sbox[8'h87] = 8'h17;
assign sbox[8'h88] = 8'hc4;
assign sbox[8'h89] = 8'ha7;
assign sbox[8'h8a] = 8'h7e;
assign sbox[8'h8b] = 8'h3d;
assign sbox[8'h8c] = 8'h64;
assign sbox[8'h8d] = 8'h5d;
assign sbox[8'h8e] = 8'h19;
assign sbox[8'h8f] = 8'h73;
assign sbox[8'h90] = 8'h60;
assign sbox[8'h91] = 8'h81;
assign sbox[8'h92] = 8'h4f;
assign sbox[8'h93] = 8'hdc;
assign sbox[8'h94] = 8'h22;
assign sbox[8'h95] = 8'h2a;
assign sbox[8'h96] = 8'h90;
assign sbox[8'h97] = 8'h88;
assign sbox[8'h98] = 8'h46;
assign sbox[8'h99] = 8'hee;
assign sbox[8'h9a] = 8'hb8;
assign sbox[8'h9b] = 8'h14;
assign sbox[8'h9c] = 8'hde;
assign sbox[8'h9d] = 8'h5e;
assign sbox[8'h9e] = 8'h0b;
assign sbox[8'h9f] = 8'hdb;
assign sbox[8'ha0] = 8'he0;
assign sbox[8'ha1] = 8'h32;
assign sbox[8'ha2] = 8'h3a;
assign sbox[8'ha3] = 8'h0a;
assign sbox[8'ha4] = 8'h49;
assign sbox[8'ha5] = 8'h06;
assign sbox[8'ha6] = 8'h24;
assign sbox[8'ha7] = 8'h5c;
assign sbox[8'ha8] = 8'hc2;
assign sbox[8'ha9] = 8'hd3;
assign sbox[8'haa] = 8'hac;
assign sbox[8'hab] = 8'h62;
assign sbox[8'hac] = 8'h91;
assign sbox[8'had] = 8'h95;
assign sbox[8'hae] = 8'he4;
assign sbox[8'haf] = 8'h79;
assign sbox[8'hb0] = 8'he7;
assign sbox[8'hb1] = 8'hc8;
assign sbox[8'hb2] = 8'h37;
assign sbox[8'hb3] = 8'h6d;
assign sbox[8'hb4] = 8'h8d;
assign sbox[8'hb5] = 8'hd5;
assign sbox[8'hb6] = 8'h4e;
assign sbox[8'hb7] = 8'ha9;
assign sbox[8'hb8] = 8'h6c;
assign sbox[8'hb9] = 8'h56;
assign sbox[8'hba] = 8'hf4;
assign sbox[8'hbb] = 8'hea;
assign sbox[8'hbc] = 8'h65;
assign sbox[8'hbd] = 8'h7a;
assign sbox[8'hbe] = 8'hae;
assign sbox[8'hbf] = 8'h08;
assign sbox[8'hc0] = 8'hba;
assign sbox[8'hc1] = 8'h78;
assign sbox[8'hc2] = 8'h25;
assign sbox[8'hc3] = 8'h2e;
assign sbox[8'hc4] = 8'h1c;
assign sbox[8'hc5] = 8'ha6;
assign sbox[8'hc6] = 8'hb4;
assign sbox[8'hc7] = 8'hc6;
assign sbox[8'hc8] = 8'he8;
assign sbox[8'hc9] = 8'hdd;
assign sbox[8'hca] = 8'h74;
assign sbox[8'hcb] = 8'h1f;
assign sbox[8'hcc] = 8'h4b;
assign sbox[8'hcd] = 8'hbd;
assign sbox[8'hce] = 8'h8b;
assign sbox[8'hcf] = 8'h8a;
assign sbox[8'hd0] = 8'h70;
assign sbox[8'hd1] = 8'h3e;
assign sbox[8'hd2] = 8'hb5;
assign sbox[8'hd3] = 8'h66;
assign sbox[8'hd4] = 8'h48;
assign sbox[8'hd5] = 8'h03;
assign sbox[8'hd6] = 8'hf6;
assign sbox[8'hd7] = 8'h0e;
assign sbox[8'hd8] = 8'h61;
assign sbox[8'hd9] = 8'h35;
assign sbox[8'hda] = 8'h57;
assign sbox[8'hdb] = 8'hb9;
assign sbox[8'hdc] = 8'h86;
assign sbox[8'hdd] = 8'hc1;
assign sbox[8'hde] = 8'h1d;
assign sbox[8'hdf] = 8'h9e;
assign sbox[8'he0] = 8'he1;
assign sbox[8'he1] = 8'hf8;
assign sbox[8'he2] = 8'h98;
assign sbox[8'he3] = 8'h11;
assign sbox[8'he4] = 8'h69;
assign sbox[8'he5] = 8'hd9;
assign sbox[8'he6] = 8'h8e;
assign sbox[8'he7] = 8'h94;
assign sbox[8'he8] = 8'h9b;
assign sbox[8'he9] = 8'h1e;
assign sbox[8'hea] = 8'h87;
assign sbox[8'heb] = 8'he9;
assign sbox[8'hec] = 8'hce;
assign sbox[8'hed] = 8'h55;
assign sbox[8'hee] = 8'h28;
assign sbox[8'hef] = 8'hdf;
assign sbox[8'hf0] = 8'h8c;
assign sbox[8'hf1] = 8'ha1;
assign sbox[8'hf2] = 8'h89;
assign sbox[8'hf3] = 8'h0d;
assign sbox[8'hf4] = 8'hbf;
assign sbox[8'hf5] = 8'he6;
assign sbox[8'hf6] = 8'h42;
assign sbox[8'hf7] = 8'h68;
assign sbox[8'hf8] = 8'h41;
assign sbox[8'hf9] = 8'h99;
assign sbox[8'hfa] = 8'h2d;
assign sbox[8'hfb] = 8'h0f;
assign sbox[8'hfc] = 8'hb0;
assign sbox[8'hfd] = 8'h54;
assign sbox[8'hfe] = 8'hbb;
assign sbox[8'hff] = 8'h16;
endmodule // aes_sbox
//======================================================================
// EOF aes_sbox.v
//======================================================================
//======================================================================
//
// aes_inv_sbox.v
// --------------
// The inverse AES S-box. Basically a 256 Byte ROM.
//
//
// Copyright (c) 2013 Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
///`default_nettype none
module aes_inv_sbox(
input wire [31 : 0] sboxw,
output wire [31 : 0] new_sboxw
);
//----------------------------------------------------------------
// The inverse sbox array.
//----------------------------------------------------------------
wire [7 : 0] inv_sbox [0 : 255];
//----------------------------------------------------------------
// Four parallel muxes.
//----------------------------------------------------------------
assign new_sboxw[31 : 24] = inv_sbox[sboxw[31 : 24]];
assign new_sboxw[23 : 16] = inv_sbox[sboxw[23 : 16]];
assign new_sboxw[15 : 08] = inv_sbox[sboxw[15 : 08]];
assign new_sboxw[07 : 00] = inv_sbox[sboxw[07 : 00]];
//----------------------------------------------------------------
// Creating the contents of the array.
//----------------------------------------------------------------
assign inv_sbox[8'h00] = 8'h52;
assign inv_sbox[8'h01] = 8'h09;
assign inv_sbox[8'h02] = 8'h6a;
assign inv_sbox[8'h03] = 8'hd5;
assign inv_sbox[8'h04] = 8'h30;
assign inv_sbox[8'h05] = 8'h36;
assign inv_sbox[8'h06] = 8'ha5;
assign inv_sbox[8'h07] = 8'h38;
assign inv_sbox[8'h08] = 8'hbf;
assign inv_sbox[8'h09] = 8'h40;
assign inv_sbox[8'h0a] = 8'ha3;
assign inv_sbox[8'h0b] = 8'h9e;
assign inv_sbox[8'h0c] = 8'h81;
assign inv_sbox[8'h0d] = 8'hf3;
assign inv_sbox[8'h0e] = 8'hd7;
assign inv_sbox[8'h0f] = 8'hfb;
assign inv_sbox[8'h10] = 8'h7c;
assign inv_sbox[8'h11] = 8'he3;
assign inv_sbox[8'h12] = 8'h39;
assign inv_sbox[8'h13] = 8'h82;
assign inv_sbox[8'h14] = 8'h9b;
assign inv_sbox[8'h15] = 8'h2f;
assign inv_sbox[8'h16] = 8'hff;
assign inv_sbox[8'h17] = 8'h87;
assign inv_sbox[8'h18] = 8'h34;
assign inv_sbox[8'h19] = 8'h8e;
assign inv_sbox[8'h1a] = 8'h43;
assign inv_sbox[8'h1b] = 8'h44;
assign inv_sbox[8'h1c] = 8'hc4;
assign inv_sbox[8'h1d] = 8'hde;
assign inv_sbox[8'h1e] = 8'he9;
assign inv_sbox[8'h1f] = 8'hcb;
assign inv_sbox[8'h20] = 8'h54;
assign inv_sbox[8'h21] = 8'h7b;
assign inv_sbox[8'h22] = 8'h94;
assign inv_sbox[8'h23] = 8'h32;
assign inv_sbox[8'h24] = 8'ha6;
assign inv_sbox[8'h25] = 8'hc2;
assign inv_sbox[8'h26] = 8'h23;
assign inv_sbox[8'h27] = 8'h3d;
assign inv_sbox[8'h28] = 8'hee;
assign inv_sbox[8'h29] = 8'h4c;
assign inv_sbox[8'h2a] = 8'h95;
assign inv_sbox[8'h2b] = 8'h0b;
assign inv_sbox[8'h2c] = 8'h42;
assign inv_sbox[8'h2d] = 8'hfa;
assign inv_sbox[8'h2e] = 8'hc3;
assign inv_sbox[8'h2f] = 8'h4e;
assign inv_sbox[8'h30] = 8'h08;
assign inv_sbox[8'h31] = 8'h2e;
assign inv_sbox[8'h32] = 8'ha1;
assign inv_sbox[8'h33] = 8'h66;
assign inv_sbox[8'h34] = 8'h28;
assign inv_sbox[8'h35] = 8'hd9;
assign inv_sbox[8'h36] = 8'h24;
assign inv_sbox[8'h37] = 8'hb2;
assign inv_sbox[8'h38] = 8'h76;
assign inv_sbox[8'h39] = 8'h5b;
assign inv_sbox[8'h3a] = 8'ha2;
assign inv_sbox[8'h3b] = 8'h49;
assign inv_sbox[8'h3c] = 8'h6d;
assign inv_sbox[8'h3d] = 8'h8b;
assign inv_sbox[8'h3e] = 8'hd1;
assign inv_sbox[8'h3f] = 8'h25;
assign inv_sbox[8'h40] = 8'h72;
assign inv_sbox[8'h41] = 8'hf8;
assign inv_sbox[8'h42] = 8'hf6;
assign inv_sbox[8'h43] = 8'h64;
assign inv_sbox[8'h44] = 8'h86;
assign inv_sbox[8'h45] = 8'h68;
assign inv_sbox[8'h46] = 8'h98;
assign inv_sbox[8'h47] = 8'h16;
assign inv_sbox[8'h48] = 8'hd4;
assign inv_sbox[8'h49] = 8'ha4;
assign inv_sbox[8'h4a] = 8'h5c;
assign inv_sbox[8'h4b] = 8'hcc;
assign inv_sbox[8'h4c] = 8'h5d;
assign inv_sbox[8'h4d] = 8'h65;
assign inv_sbox[8'h4e] = 8'hb6;
assign inv_sbox[8'h4f] = 8'h92;
assign inv_sbox[8'h50] = 8'h6c;
assign inv_sbox[8'h51] = 8'h70;
assign inv_sbox[8'h52] = 8'h48;
assign inv_sbox[8'h53] = 8'h50;
assign inv_sbox[8'h54] = 8'hfd;
assign inv_sbox[8'h55] = 8'hed;
assign inv_sbox[8'h56] = 8'hb9;
assign inv_sbox[8'h57] = 8'hda;
assign inv_sbox[8'h58] = 8'h5e;
assign inv_sbox[8'h59] = 8'h15;
assign inv_sbox[8'h5a] = 8'h46;
assign inv_sbox[8'h5b] = 8'h57;
assign inv_sbox[8'h5c] = 8'ha7;
assign inv_sbox[8'h5d] = 8'h8d;
assign inv_sbox[8'h5e] = 8'h9d;
assign inv_sbox[8'h5f] = 8'h84;
assign inv_sbox[8'h60] = 8'h90;
assign inv_sbox[8'h61] = 8'hd8;
assign inv_sbox[8'h62] = 8'hab;
assign inv_sbox[8'h63] = 8'h00;
assign inv_sbox[8'h64] = 8'h8c;
assign inv_sbox[8'h65] = 8'hbc;
assign inv_sbox[8'h66] = 8'hd3;
assign inv_sbox[8'h67] = 8'h0a;
assign inv_sbox[8'h68] = 8'hf7;
assign inv_sbox[8'h69] = 8'he4;
assign inv_sbox[8'h6a] = 8'h58;
assign inv_sbox[8'h6b] = 8'h05;
assign inv_sbox[8'h6c] = 8'hb8;
assign inv_sbox[8'h6d] = 8'hb3;
assign inv_sbox[8'h6e] = 8'h45;
assign inv_sbox[8'h6f] = 8'h06;
assign inv_sbox[8'h70] = 8'hd0;
assign inv_sbox[8'h71] = 8'h2c;
assign inv_sbox[8'h72] = 8'h1e;
assign inv_sbox[8'h73] = 8'h8f;
assign inv_sbox[8'h74] = 8'hca;
assign inv_sbox[8'h75] = 8'h3f;
assign inv_sbox[8'h76] = 8'h0f;
assign inv_sbox[8'h77] = 8'h02;
assign inv_sbox[8'h78] = 8'hc1;
assign inv_sbox[8'h79] = 8'haf;
assign inv_sbox[8'h7a] = 8'hbd;
assign inv_sbox[8'h7b] = 8'h03;
assign inv_sbox[8'h7c] = 8'h01;
assign inv_sbox[8'h7d] = 8'h13;
assign inv_sbox[8'h7e] = 8'h8a;
assign inv_sbox[8'h7f] = 8'h6b;
assign inv_sbox[8'h80] = 8'h3a;
assign inv_sbox[8'h81] = 8'h91;
assign inv_sbox[8'h82] = 8'h11;
assign inv_sbox[8'h83] = 8'h41;
assign inv_sbox[8'h84] = 8'h4f;
assign inv_sbox[8'h85] = 8'h67;
assign inv_sbox[8'h86] = 8'hdc;
assign inv_sbox[8'h87] = 8'hea;
assign inv_sbox[8'h88] = 8'h97;
assign inv_sbox[8'h89] = 8'hf2;
assign inv_sbox[8'h8a] = 8'hcf;
assign inv_sbox[8'h8b] = 8'hce;
assign inv_sbox[8'h8c] = 8'hf0;
assign inv_sbox[8'h8d] = 8'hb4;
assign inv_sbox[8'h8e] = 8'he6;
assign inv_sbox[8'h8f] = 8'h73;
assign inv_sbox[8'h90] = 8'h96;
assign inv_sbox[8'h91] = 8'hac;
assign inv_sbox[8'h92] = 8'h74;
assign inv_sbox[8'h93] = 8'h22;
assign inv_sbox[8'h94] = 8'he7;
assign inv_sbox[8'h95] = 8'had;
assign inv_sbox[8'h96] = 8'h35;
assign inv_sbox[8'h97] = 8'h85;
assign inv_sbox[8'h98] = 8'he2;
assign inv_sbox[8'h99] = 8'hf9;
assign inv_sbox[8'h9a] = 8'h37;
assign inv_sbox[8'h9b] = 8'he8;
assign inv_sbox[8'h9c] = 8'h1c;
assign inv_sbox[8'h9d] = 8'h75;
assign inv_sbox[8'h9e] = 8'hdf;
assign inv_sbox[8'h9f] = 8'h6e;
assign inv_sbox[8'ha0] = 8'h47;
assign inv_sbox[8'ha1] = 8'hf1;
assign inv_sbox[8'ha2] = 8'h1a;
assign inv_sbox[8'ha3] = 8'h71;
assign inv_sbox[8'ha4] = 8'h1d;
assign inv_sbox[8'ha5] = 8'h29;
assign inv_sbox[8'ha6] = 8'hc5;
assign inv_sbox[8'ha7] = 8'h89;
assign inv_sbox[8'ha8] = 8'h6f;
assign inv_sbox[8'ha9] = 8'hb7;
assign inv_sbox[8'haa] = 8'h62;
assign inv_sbox[8'hab] = 8'h0e;
assign inv_sbox[8'hac] = 8'haa;
assign inv_sbox[8'had] = 8'h18;
assign inv_sbox[8'hae] = 8'hbe;
assign inv_sbox[8'haf] = 8'h1b;
assign inv_sbox[8'hb0] = 8'hfc;
assign inv_sbox[8'hb1] = 8'h56;
assign inv_sbox[8'hb2] = 8'h3e;
assign inv_sbox[8'hb3] = 8'h4b;
assign inv_sbox[8'hb4] = 8'hc6;
assign inv_sbox[8'hb5] = 8'hd2;
assign inv_sbox[8'hb6] = 8'h79;
assign inv_sbox[8'hb7] = 8'h20;
assign inv_sbox[8'hb8] = 8'h9a;
assign inv_sbox[8'hb9] = 8'hdb;
assign inv_sbox[8'hba] = 8'hc0;
assign inv_sbox[8'hbb] = 8'hfe;
assign inv_sbox[8'hbc] = 8'h78;
assign inv_sbox[8'hbd] = 8'hcd;
assign inv_sbox[8'hbe] = 8'h5a;
assign inv_sbox[8'hbf] = 8'hf4;
assign inv_sbox[8'hc0] = 8'h1f;
assign inv_sbox[8'hc1] = 8'hdd;
assign inv_sbox[8'hc2] = 8'ha8;
assign inv_sbox[8'hc3] = 8'h33;
assign inv_sbox[8'hc4] = 8'h88;
assign inv_sbox[8'hc5] = 8'h07;
assign inv_sbox[8'hc6] = 8'hc7;
assign inv_sbox[8'hc7] = 8'h31;
assign inv_sbox[8'hc8] = 8'hb1;
assign inv_sbox[8'hc9] = 8'h12;
assign inv_sbox[8'hca] = 8'h10;
assign inv_sbox[8'hcb] = 8'h59;
assign inv_sbox[8'hcc] = 8'h27;
assign inv_sbox[8'hcd] = 8'h80;
assign inv_sbox[8'hce] = 8'hec;
assign inv_sbox[8'hcf] = 8'h5f;
assign inv_sbox[8'hd0] = 8'h60;
assign inv_sbox[8'hd1] = 8'h51;
assign inv_sbox[8'hd2] = 8'h7f;
assign inv_sbox[8'hd3] = 8'ha9;
assign inv_sbox[8'hd4] = 8'h19;
assign inv_sbox[8'hd5] = 8'hb5;
assign inv_sbox[8'hd6] = 8'h4a;
assign inv_sbox[8'hd7] = 8'h0d;
assign inv_sbox[8'hd8] = 8'h2d;
assign inv_sbox[8'hd9] = 8'he5;
assign inv_sbox[8'hda] = 8'h7a;
assign inv_sbox[8'hdb] = 8'h9f;
assign inv_sbox[8'hdc] = 8'h93;
assign inv_sbox[8'hdd] = 8'hc9;
assign inv_sbox[8'hde] = 8'h9c;
assign inv_sbox[8'hdf] = 8'hef;
assign inv_sbox[8'he0] = 8'ha0;
assign inv_sbox[8'he1] = 8'he0;
assign inv_sbox[8'he2] = 8'h3b;
assign inv_sbox[8'he3] = 8'h4d;
assign inv_sbox[8'he4] = 8'hae;
assign inv_sbox[8'he5] = 8'h2a;
assign inv_sbox[8'he6] = 8'hf5;
assign inv_sbox[8'he7] = 8'hb0;
assign inv_sbox[8'he8] = 8'hc8;
assign inv_sbox[8'he9] = 8'heb;
assign inv_sbox[8'hea] = 8'hbb;
assign inv_sbox[8'heb] = 8'h3c;
assign inv_sbox[8'hec] = 8'h83;
assign inv_sbox[8'hed] = 8'h53;
assign inv_sbox[8'hee] = 8'h99;
assign inv_sbox[8'hef] = 8'h61;
assign inv_sbox[8'hf0] = 8'h17;
assign inv_sbox[8'hf1] = 8'h2b;
assign inv_sbox[8'hf2] = 8'h04;
assign inv_sbox[8'hf3] = 8'h7e;
assign inv_sbox[8'hf4] = 8'hba;
assign inv_sbox[8'hf5] = 8'h77;
assign inv_sbox[8'hf6] = 8'hd6;
assign inv_sbox[8'hf7] = 8'h26;
assign inv_sbox[8'hf8] = 8'he1;
assign inv_sbox[8'hf9] = 8'h69;
assign inv_sbox[8'hfa] = 8'h14;
assign inv_sbox[8'hfb] = 8'h63;
assign inv_sbox[8'hfc] = 8'h55;
assign inv_sbox[8'hfd] = 8'h21;
assign inv_sbox[8'hfe] = 8'h0c;
assign inv_sbox[8'hff] = 8'h7d;
endmodule // aes_inv_sbox
//======================================================================
// EOF aes_inv_sbox.v
//======================================================================
// 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
......@@ -84,11 +84,14 @@ read_verilog $soc_vlog/verilog/nanosoc_mcu_sysctrl.v
read_verilog $soc_vlog/verilog/nanosoc_cpu.v
read_verilog $soc_vlog/verilog/nanosoc_sys_ahb_decode.v
read_verilog $soc_vlog/verilog/nanosoc_sysio.v
read_verilog ../aes/src/soclabs_ahb_aes128_ctrl.v
read_verilog ../aes/src/nanosoc_acc_wrapper.v
read_verilog $soc_vlog/verilog/nanosoc_chip.v
read_verilog $soc_vlog/verilog/nanosoc_chip_pads.v
set search_path [ concat $search_path ../../../secworks-aes/src/rtl ]
read_verilog ../aes/src/soclabs_ahb_aes128_ctrl.v
set_property generic {NANOSOC_EXPANSION_REGION=1} [current_fileset]
#set_property generic {NANOSOC_EXPANSION_REGION=1} [current_fileset]
set_property verilog_define {NANOSOC_EXPANSION_REGION=1} [current_fileset]
set_property top nanosoc_chip [current_fileset]
# FPGA specific timing constraints
......
......@@ -6,7 +6,7 @@
#
# David Flynn (d.w.flynn@soton.ac.uk)
#
# Copyright 2021-3, SoC Labs (www.soclabs.org)
# Copyright (C) 2021-3, SoC Labs (www.soclabs.org)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
......@@ -81,21 +81,21 @@ BOOTROM_HEX ?= $(NANOSOC_TECH_DIR)/system/testcodes/bootloader/$(BOOTLOADE
BOOTROM_BUILD_DIR ?= $(NANOSOC_TECH_DIR)/system/src/bootrom
NANSOC_EXPANSION_REGION ?= yes
NANOSOC_EXPANSION_REGION ?= yes
# Simulator Defines
DEFINES_VC += $(MEM_INIT) +define+CORTEX_M0 +define+USE_TARMAC
ifeq ($(NANSOC_EXPANSION_REGION),yes)
DEFINES_VC += +define+NANSOC_EXPANSION_REGION
ifeq ($(NANOSOC_EXPANSION_REGION),yes)
DEFINES_VC += +define+NANOSOC_EXPANSION_REGION
endif
# Simulator Command file to specify RTL source files
TBENCH_VC ?= -f $(PROJECT_DIR)/flist/project/system.flist
TBENCH_VC ?= $(PROJECT_DIR)/flist/project/system.flist
# Simulator type (mti/vcs/xm)
SIMULATOR = xm
SIMULATOR = mti
# Directory to put simulation files
SIM_TOP_DIR ?= $(PROJECT_DIR)/simulate/sim
......@@ -105,16 +105,16 @@ SIM_DIR = $(SIM_TOP_DIR)/$(TESTNAME)
# MTI option
#DF#MTI_OPTIONS = -novopt
MTI_OPTIONS = -suppress 2892
MTI_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC)
MTI_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS)
# VCS option
VCS_OPTIONS = +vcs+lic+wait +v2k +lint=all,noTMR,noVCDE -debug
VCS_SIM_OPTION = +vcs+lic+wait +vcs+flush+log -assert nopostproc
VCS_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC)
VCS_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS)
# XM verilog option
XMSIM_OPTIONS = -unbuffered -status -LICQUEUE -f xmsim.args -cdslib cds.lib -hdlvar hdl.var -NBASYNC
XM_VC_OPTIONS = $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS)
XM_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS)
# Debug Tester image
......@@ -142,7 +142,7 @@ all : all_$(SIMULATOR)
# Compile RTL
compile_vcs :
vcs $(VCS_OPTIONS) $(VCS_VC_OPTIONS) | tee compile_vcs.log
vcs $(VCS_OPTIONS) $(VCS_VC_OPTIONS) $(DEFINES_VC) | tee compile_vcs.log
# Run simulation in batch mode
......@@ -227,31 +227,37 @@ all_xm : compile_xm bootrom debugtester
# ------- MTI -----------
# Compile RTL
compile_mti :
compile_mti : bootrom
@echo ADP_FILE
@echo $(ADP_OPTIONS)
cd $(SIM_DIR)
@if [ -d work ] ; then \
true ; \
else \
vlib work; \
fi
vlog -incr -lint +v2k $(MTI_OPTIONS) $(MTI_VC_OPTIONS) | tee compile_mti.log
cd $(SIM_DIR); vlog -incr -lint +v2k $(MTI_OPTIONS) $(MTI_VC_OPTIONS) $(DEFINES_VC) | tee compile_mti.log
# Run simulation in batch mode
run_mti : code
@if [ ! -d logs ] ; then \
mkdir logs; \
run_mti : code compile_mti
@if [ ! -d $(SIM_DIR)/logs ] ; then \
mkdir $(SIM_DIR)/logs; \
fi
vsim $(MTI_OPTIONS) -c tb_cmsdk_mcu -do "radix hex;run -all;quit -f" | tee logs/run_$(TESTNAME).log ;
@echo "run -all" > $(SIM_DIR)/run.tcl.tmp
@echo "quit -f" >> $(SIM_DIR)/run.tcl.tmp
@mv $(SIM_DIR)/run.tcl.tmp $(SIM_DIR)/run.tcl
cd $(SIM_DIR); vsim $(MTI_OPTIONS) -c nanosoc_tb -do run.tcl | tee logs/run_$(TESTNAME).log ;
# Run simulation in interactive mode
sim_mti : code
vsim $(MTI_OPTIONS) -gui tb_cmsdk_mcu &
sim_mti : code compile_mti
vsim $(MTI_OPTIONS) -gui nanosoc_tb &
# Create work directory
lib_mti :
vlib work
# Compile RTL, and run all tests in batch mode
all_mti : compile_mti bootrom debugtester
all_mti : bootrom compile_mti debugtester
@if [ ! -d logs ] ; then \
mkdir logs; \
fi
......@@ -320,6 +326,7 @@ endif
if [ -e $(TESTNAME).hex ] ; then \
mkdir -p $(SIM_DIR) ; \
cp $(TESTNAME).hex $(SIM_DIR)/image.hex ; \
cp $(TESTNAME).hex ../../image.hex ; \
else \
echo Problem reading hex file ;\
exit 1; \
......@@ -427,7 +434,7 @@ v2html:
fi
@(cd $(NANOSOC_HTML_DIR)/build; \
rm *.html; rm *.gif; rm *.gz; \
~/tools/v2html -f $(VERILOG_DIR)/v2html_M0.vc -ht nanosoc_chip ; \
~/tools/v2html -f $(PROJECT_DIR)/flist/project/v2html_system.flist -ht nanosoc_chip ; \
cp -p nanosoc_tb.v.html hierarchy.html ; \
cd $(SIM_DIR) ; )
gtar zcvf $(NANOSOC_HTML_DIR)/v2html_doc.tgz $(NANOSOC_HTML_DIR)/build
......
......@@ -833,17 +833,24 @@ localparam CORTEX_M0 = 1;
//
// ************************************************
wire exp_ip_req;
wire exp_op_req;
wire exp_irq;
//----------------------------------------
wire exp_drq_ip;
wire exp_drq_op;
wire [3:0] exp_irq;
wire exp_merged_irq;
assign exp_irq0 = exp_irq[0];
assign exp_irq1 = exp_irq[1];
assign exp_irq2 = exp_irq[2];
assign exp_irq3 = exp_irq[3];
//----------------------------------------
// Expansion Region "exp" instance
//----------------------------------------
`ifdef NANSOC_EXPANSION_REGION
nanosoc_exp #(.ADDRWIDTH(29)
) u_nanosoc_exp (
`ifdef NANOSOC_EXPANSION_REGION
nanosoc_acc_wrapper #(
.AHBADDRWIDTH(29),
.CFGNUMIRQ(4)
) u_nanosoc_exp_wrapper (
.HCLK (HCLK),
.HRESETn (HRESETn),
......@@ -860,8 +867,11 @@ nanosoc_exp #(.ADDRWIDTH(29)
.HREADYOUTS (HREADYOUT_exp),
.HRESPS (HRESP_exp),
.HRDATAS (HRDATA_exp),
.ip_data_req (exp_ip_req),
.op_data_req (exp_op_req)
.exp_drq_ip_o (exp_drq_ip),
.exp_dlast_ip_i(1'b0),
.exp_drq_op_o (exp_drq_op),
.exp_dlast_op_i(1'b0),
.exp_irq_o (exp_irq)
);
`else
// Default slave - if no expansion region
......@@ -876,6 +886,30 @@ nanosoc_exp #(.ADDRWIDTH(29)
);
assign HRDATA_exp = 32'heaedeaed; // Tie off Expansion Address Expansion Data
//nanosoc_exp_wrapper #(.AHBADDRWIDTH(29)
//) u_nanosoc_exp_wrapper (
// .HCLK (HCLK),
// .HRESETn (HRESETn),
//
// // Input slave port: 32 bit data bus interface
// .HSEL_i (HSEL_exp),
// .HADDR_i (HADDR_exp[28:0]),
// .HTRANS_i (HTRANS_exp),
// .HSIZE_i (HSIZE_exp),
// .HPROT_i (HPROT_exp),
// .HWRITE_i (HWRITE_exp),
// .HREADY_i (HREADYMUX_exp),
// .HWDATA_i (HWDATA_exp),
//
// .HREADYOUT_o (HREADYOUT_exp),
// .HRESP_o (HRESP_exp),
// .HRDATA_o (HRDATA_exp),
// .exp_drq_ip_o (exp_drq_ip),
// .exp_dlast_ip_i(1'b0),
// .exp_drq_op_o (exp_drq_op),
// .exp_dlast_op_i(1'b0),
// .exp_irq_o (exp_irq)
//);
`endif
assign HRUSER_exp = 2'b00;
......@@ -1262,8 +1296,8 @@ localparam AWRAM9 = ADDR_WIDTH_RAM; // Address width - to match RAM instance siz
wire [DMA_CHANNEL_NUM-1:0] dma230_req; // tie off signal.
wire [DMA_CHANNEL_NUM-1:0] dma230_tie0 = {DMA_CHANNEL_NUM{1'b0}};
assign dma230_req[0] = exp_ip_req;
assign dma230_req[1] = exp_op_req;
assign dma230_req[0] = exp_drq_ip;
assign dma230_req[1] = exp_drq_op;
// DMA done per channel
......
......@@ -11,7 +11,7 @@
//`define ADPBASIC 1
`begin_keywords "1364-2001"
//`begin_keywords "1364-2001"
module nanosoc_adp_manager // AHB initiator interface
#(parameter PROMPT_CHAR = "]"
......@@ -181,8 +181,8 @@ endfunction
function [63:0] FNBuild_param64_byte;
input [63:0] param64;
input [7:0] byte;
FNBuild_param64_byte = {byte[7:0], param64[63:08]};
input [7:0] octet;
FNBuild_param64_byte = {octet[7:0], param64[63:08]};
endfunction
function [31:0] FNBuild_param32_hexdigit;
......@@ -221,8 +221,8 @@ endfunction
function [31:0] FNBuild_param32_byte;
input [31:0] param32;
input [7:0] byte;
FNBuild_param32_byte = {byte[7:0], param32[31:08]};
input [7:0] octet;
FNBuild_param32_byte = {octet[7:0], param32[31:08]};
endfunction
......@@ -453,8 +453,8 @@ input [3:0] nibble;
begin com_tx_req <= 1; com_tx_byte <= FNmap_hex_digit(nibble[3:0]); end
endtask
task ADP_txchar_next; // output char
input [7:0] byte;
begin com_tx_req<= 1; com_tx_byte <= byte; end
input [7:0] octet;
begin com_tx_req<= 1; com_tx_byte <= octet; end
endtask
task com_rx_nxt; com_rx_ack <=1; endtask
......@@ -764,7 +764,7 @@ always @(posedge HCLK or negedge HRESETn)
endmodule
`end_keywords
//`end_keywords
////AHBLITE_ADPMASTER instancing
//ADPmaster
......
#ifndef _AES128_H_
#define _AES128_H_
#include <stdint.h>
// define the API addresses here.
#define AES128_BASE (0x60000000)
// byte address I/O buffers
#define AES128_BUF_SIZE (0x4000)
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 */
uint8_t RESRV50[AES128_BUF_SIZE - 0x50];/* 0x0050-0x3FFC (4096-20 words) */
__IO uint8_t KEY128[AES128_BUF_SIZE]; /* 0x4000-7FFF (0x3FFF is last alias) */
__IO uint8_t TXTIP128[AES128_BUF_SIZE]; /* 0x8000-BFFF (0x3FFF is last alias) */
__I uint8_t TXTOP128[AES128_BUF_SIZE]; /* 0xC000-FFFF (0x3FFF is last alias) */
} AES128_TypeDef;
#define AES128 ((AES128_TypeDef *) AES128_BASE )
#define AES_BLOCK_SIZE 16
#define AES_KEY_LEN_128 16
#define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS)))
#define AES128_CTRL_REG_WIDTH ( 8)
#define AES128_CTRL_BIT_MAX ( (CTRL_REG_WIDTH-1)
#define AES128_CTRL_KEY_REQ_BIT (1<<0)
#define AES128_CTRL_IP_REQ_BIT (1<<1)
#define AES128_CTRL_OP_REQ_BIT (1<<2)
#define AES128_CTRL_ERR_REQ_BIT (1<<3)
#define AES128_CTRL_BYPASS_BIT (1<<6)
#define AES128_CTRL_ENCODE_BIT (1<<7)
#define AES128_STAT_REG_WIDTH ( 8)
#define AES128_STAT_KEY_REQ_BIT (1<<0)
#define AES128_STAT_IP_REQ_BIT (1<<1)
#define AES128_STAT_OP_REQ_BIT (1<<2)
#define AES128_STAT_ERR_REQ_BIT (1<<3)
#define AES128_STAT_KEYOK_BIT (1<<4)
#define AES128_STAT_VALID_BIT (1<<5)
#define AES128_STAT_BYPASS_BIT (1<<6)
#define AES128_STAT_ENCODE_BIT (1<<7)
#define AES128_KEY_REQ_BIT (1<<0)
#define AES128_IP_REQ_BIT (1<<1)
#define AES128_OP_REQ_BIT (1<<2)
#define AES128_ERR_REQ_BIT (1<<3)
#define AES128_KEYOK_BIT (1<<4)
#define AES128_VALID_BIT (1<<5)
#define AES128_BYPASS_BIT (1<<6)
#define AES128_ENCODE_BIT (1<<7)
#endif // _AES128_H_
#include "CMSDK_CM0.h"
#include "aes128.h"
#include <string.h>
#include "uart_stdout.h"
#include <stdio.h>
// memcopy implememtation
#define os_memcpy memcpy
#define os_memset memset
// PL230DMA implementation
#include "dma_pl230_driver.h"
static volatile dma_pl230_channel_data aes_ip_chain[2];
static volatile dma_pl230_channel_data aes_op_chain[2];
// associate DMA channel numbers
#define DMA_CHAN_AES128_IP (0)
#define DMA_CHAN_AES128_OP (1)
volatile int dma_done_irq_occurred;
volatile int dma_done_irq_expected;
volatile int dma_error_irq_occurred;
volatile int dma_error_irq_expected;
volatile int aes_key_irq_occurred;
volatile int aes_key_irq_expected;
volatile int aes_ip_irq_occurred;
volatile int aes_ip_irq_expected;
volatile int aes_op_irq_occurred;
volatile int aes_op_irq_expected;
volatile int aes_err_irq_occurred;
volatile int aes_err_irq_expected;
uint8_t _test_key128[AES_KEY_LEN_128] = {
0x75, 0x46, 0x20, 0x67,
0x6e, 0x75, 0x4b, 0x20,
0x79, 0x6d, 0x20, 0x73,
0x74, 0x61, 0x68, 0x54 };
uint8_t test_key128[AES_KEY_LEN_128] = {
0x54, 0x68, 0x61, 0x74,
0x73, 0x20, 0x6d, 0x79,
0x20, 0x4b, 0x75, 0x6e,
0x67, 0x20, 0x46, 0x75 };
uint8_t buf128[AES_BLOCK_SIZE] = {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
uint8_t _test_text128[AES_BLOCK_SIZE] = {
0x6f, 0x77, 0x54, 0x20,
0x65, 0x6e, 0x69, 0x4e,
0x20, 0x65, 0x6e, 0x4f,
0x20, 0x6f, 0x77, 0x54 };
uint8_t test_text128[AES_BLOCK_SIZE] = {
0x54, 0x77, 0x6f, 0x20,
0x4f, 0x6e, 0x65, 0x20,
0x4e, 0x69, 0x6e, 0x65,
0x20, 0x54, 0x77, 0x6f };
uint8_t test_exp128[AES_BLOCK_SIZE] = {
0x29, 0xc3, 0x50, 0x5f,
0x57, 0x14, 0x20, 0xf6,
0x40, 0x22, 0x99, 0xb3,
0x1a, 0x02, 0xd7, 0x3a };
// add extra block[128] with all zeros to toggle bits low
uint8_t shift_patt[129*16] = {
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//127
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//128
};
uint8_t shift_buf1[sizeof(shift_patt)];
uint8_t shift_buf2[sizeof(shift_patt)];
/* Note: Hardware supports byte, half-word or word accesses
So memcpy() can be used to load/save data
And memset() can be used to pad out data-in to 128-bits
mode =0 (bypass), =1 (encode) or =2 (decode)
*/
void aes128_driver_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input,
uint8_t *result, uint8_t mode)
{
// Reset engine
AES128->DRQ_MSK = 0;
AES128->IRQ_MSK = 0;
AES128->QUAL = 0;
AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT | AES128_CTRL_ERR_REQ_BIT;
// Set up parameters
if (mode == 1)
AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
if (mode == 0)
AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
// Program Key
os_memcpy((uint8_t *)AES128->KEY128, key, AES_KEY_LEN_128);
while (!(AES128->STATUS & AES128_KEYOK_BIT))
;
/* payload */
while(nbytes) {
uint8_t len = (nbytes > AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : nbytes;
/* Align/pad input and load into hardware */
os_memcpy((uint8_t *)AES128->TXTIP128, input, len);
//patch up any zero-padding
if (len < AES_BLOCK_SIZE)
os_memset((uint8_t *)&(AES128->TXTIP128[len]), 0, AES_BLOCK_SIZE-len);
/* Auto-started! - no need for manual start */
/* Poll until completed */
while (!(AES128->STATUS & AES128_VALID_BIT))
;
os_memcpy(result, (uint8_t *)AES128->TXTOP128, AES_BLOCK_SIZE);
/* Accounting */
input += len;
result += len;
nbytes -= len;
AES128->IRQ_MSK_SET = (AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
}
AES128->CTRL = 0;
}
// wrapper functions
void aes128_bypass_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_driver_memcpy(key, nbytes, input, result, 0); }
void aes128_encrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_driver_memcpy(key, nbytes, input, result, 1); }
void aes128_decrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_driver_memcpy(key, nbytes, input, result, 2); }
int aes128_buffer_verify(uint32_t buflen, uint8_t *buf_A, uint8_t *buf_B)
{
int i, j, fail = 0;
for (i=0 ; i < buflen; i++) {
if (buf_A[i] != buf_B[i]){
fail = 1;
break;
}
}
if (fail) {
j=i; // print offending block
for (i=(j - (j%16)) ; i < (j-(j%16)+16); i++) {
if (i%16==0)
printf(" //%03d\n", (i>>4));
printf("0x%02x,", buf_A[i]);
}
}
if (fail){
i=j;
printf("Verify compare FAIL\n EXPECTED_RESULT[%2d]= 0x%02x, ACTUAL_RESULT= 0x%02x \n",i, buf_B[i], buf_A[i]);
return(-1);
}
return(0);
}
void aes128_driver_aligned_dma32(uint8_t *key, uint32_t nbytes, uint8_t *input,
uint8_t *result, uint8_t mode)
{
int c;
// Reset engine
AES128->DRQ_MSK = 0;
AES128->IRQ_MSK = 0;
AES128->QUAL = 0;
AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT;
// Set up parameters
if (mode == 1)
AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
if (mode == 0)
AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
dma_pl230_data_struct_init(); // initialize
// program DMA transfers in multiples of 4 words (nbytes scaled >>2 for words)
aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_W,4);
aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_W,4);
aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_W,4,PL230_CTRL_RPWR_4);
aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_W,(nbytes>>2));
aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2));
aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4);
c=DMA_CHAN_AES128_IP;
dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W,(2*4));
dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4);
aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2));
aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_W,(nbytes>>2));
aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4);
c=DMA_CHAN_AES128_OP;
dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4));
dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4);
// enable DMA controller channels
dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active
// and enable DMA requests
AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
// test to ensure output DMA has started
while (!(dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))))
;
while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))
;
while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))
;
AES128->DRQ_MSK = 0;
AES128->IRQ_MSK = 0;
DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
dma_pl230_init(0); // none active
return;
}
void aes128_driver_dma8(uint8_t *key, uint32_t nbytes, uint8_t *input,
uint8_t *result, uint8_t mode)
{
int c;
// Reset engine
AES128->DRQ_MSK = 0;
AES128->IRQ_MSK = 0;
AES128->QUAL = 0;
AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT;
// Set up parameters
if (mode == 1)
AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
if (mode == 0)
AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
dma_pl230_data_struct_init(); // initialize
// program DMA transfers in multiples of 16 bytes
aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_B,16);
aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_B,16);
aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_B,16,PL230_CTRL_RPWR_16);
aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_B,(nbytes));
aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes));
aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16);
c=DMA_CHAN_AES128_IP;
dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W, (2*4));
dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W, (1*4));
dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4);
aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes));
aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_B,(nbytes));
aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16);
c=DMA_CHAN_AES128_OP;
dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4));
dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4);
// enable DMA controller channels
dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active
// and enable DMA requests
AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
// test to ensure output DMA has started
while (!(dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)))
;
while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))
;
while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))
;
AES128->DRQ_MSK = 0;
AES128->IRQ_MSK = 0;
DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
dma_pl230_init(0); // none active
return;
}
// wrapper functions
void aes128_alignchk_block_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result, uint8_t mode)
{ uint32_t dma_max = DMA_PL230_MAX_XFERS; // default to 1 K bytes
if (((((long)key) & 3)==0) && ((((long)input) & 3)==0) && ((((long)result) & 3)==0)) dma_max=(DMA_PL230_MAX_XFERS<<2);
while (nbytes >dma_max) {
if (dma_max == DMA_PL230_MAX_XFERS) // 1K bytes DMA
aes128_driver_dma8(key, dma_max, input, result, mode);
else // 1K words DMA
aes128_driver_aligned_dma32(key, dma_max, input, result, mode);
nbytes -= dma_max; input += dma_max; result += dma_max;
}
if (dma_max == DMA_PL230_MAX_XFERS) // up to 1K bytes remaining
aes128_driver_dma8(key, nbytes, input, result, mode);
else // up to 1K words remaining
aes128_driver_aligned_dma32(key, nbytes, input, result, mode);
}
void aes128_bypass_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_alignchk_block_dma (key, nbytes, input, result, 0); }
void aes128_encrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_alignchk_block_dma (key, nbytes, input, result, 1); }
void aes128_decrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
{ aes128_alignchk_block_dma (key, nbytes, input, result, 2); }
int main(void) {
char rx_char [256] = "soclabs AES128v1"; // init to 0
unsigned char id_string [16] = {0};
int i, fail=0;
unsigned char * p;
UartStdOutInit();
printf("%s\n",rx_char);
printf("AES128 test program\n");
printf(" AES128 ID: ");
// iterate over 3 32-bit fields
p = (unsigned char *)AES128->CORE_NAME;
for (i = 0; i < 12; i++) {
id_string[i^3]=*p; // fix byte ordering per word
p+=1;
}
id_string[12] = 0;
printf("%s\n",id_string);
aes_key_irq_occurred = 0;
aes_key_irq_expected = 1;
NVIC_ClearPendingIRQ(EXP0_IRQn);
NVIC_EnableIRQ(EXP0_IRQn);
aes_ip_irq_occurred = 0;
aes_ip_irq_expected = 1;
NVIC_ClearPendingIRQ(EXP1_IRQn);
NVIC_EnableIRQ(EXP1_IRQn);
aes_op_irq_occurred = 0;
aes_op_irq_expected = 1;
NVIC_ClearPendingIRQ(EXP2_IRQn);
NVIC_EnableIRQ(EXP2_IRQn);
aes_err_irq_occurred = 0;
aes_err_irq_expected = 1;
NVIC_ClearPendingIRQ(EXP3_IRQn);
NVIC_EnableIRQ(EXP3_IRQn);
printf("AES128 SW (memcpy) tests...\n");
printf(" AES128 reference pattern test\n");
printf(" AES128 input/output bypass test\n");
aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
if (aes_key_irq_occurred != 1){ fail++;
printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
if (aes_ip_irq_occurred != 2){ fail++;
printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
if (aes_op_irq_occurred != 1){ fail++;
printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
if (aes_err_irq_occurred != 0){ fail++;
printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
printf(" AES128 encrypt test\n");
aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128);
printf(" AES128 decrypt test\n");
aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
aes_key_irq_occurred = 0;
aes_ip_irq_occurred = 0;
aes_op_irq_occurred = 0;
aes_err_irq_occurred = 0;
printf(" AES128 logic toggle test\n");
printf(" AES128 input/output pattern test\n");
aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1);
fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt);
if (aes_key_irq_occurred != 1){ fail++;
printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
if (aes_ip_irq_occurred != (129+1)){ fail++;
printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
if (aes_op_irq_occurred != 129){ fail++;
printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
if (aes_err_irq_occurred != 0){ fail++;
printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
printf(" AES128 pattern encrypt test\n");
aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1);
printf(" AES128 pattern decrypt test\n");
aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2);
fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt);
printf("AES128 DMA tests...\n");
aes_key_irq_occurred = 0;
aes_ip_irq_occurred = 0;
aes_op_irq_occurred = 0;
aes_err_irq_occurred = 0;
dma_error_irq_expected = 0;
dma_error_irq_occurred = 0;
dma_done_irq_expected = 1;
dma_done_irq_occurred = 0;
NVIC_ClearPendingIRQ(DMA_IRQn);
NVIC_EnableIRQ(DMA_IRQn);
printf(" AES128 dma input/output bypass test\n");
aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
if (dma_done_irq_occurred < 2){
puts ("ERROR: DMA err IRQ missing");
fail++;
} else
printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
printf(" AES128 dma encrypt test\n");
aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128);
printf(" AES128 dma decrypt test\n");
aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128);
fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
if (dma_done_irq_occurred < 6){
puts ("ERROR: DMA err IRQ missing");
fail++;
} else
printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
printf(" AES128 dma unaligned pattern test\n");
aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3);
fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt);
printf(" AES128 dma input/output pattern test\n");
aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1);
fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt);
printf(" AES128 dma pattern encrypt test\n");
aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1);
printf(" AES128 dma pattern decrypt test\n");
aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2);
fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt);
if (dma_done_irq_occurred < (2*7)){
puts ("ERROR: DMA err IRQ missing");
fail++;
} else
printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
// check IRQ masked by DRQs - except when Iinput buffer empty after DMA done
if (aes_key_irq_occurred != 0){ fail++;
printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
if (aes_ip_irq_occurred != 7){ fail++;
printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
if (aes_op_irq_occurred != 0){ fail++;
printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
if (aes_err_irq_occurred != 0){ fail++;
printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
NVIC_DisableIRQ(DMA_IRQn);
NVIC_DisableIRQ(EXP0_IRQn);
NVIC_DisableIRQ(EXP1_IRQn);
NVIC_DisableIRQ(EXP2_IRQn);
NVIC_DisableIRQ(EXP3_IRQn);
printf ("Data retrieved from the AES is: %s\n", id_string);
printf ("Data expected from the AES is: %s\n", rx_char);
if (fail >0)
printf("** AES TESTS FAILED (%d) **\n", fail);
else
printf("** AES TEST PASSED **\n");
// End simulation
UartEndSimulation();
return 0;
}
/* --------------------------------------------------------------- */
/* Interrupt handlers */
/* --------------------------------------------------------------- */
void DMA_Handler(void)
{
if ((DMA_PL230_DMAC->ERR_CLR & 1) != 0) {
/* DMA interrupt is caused by DMA error */
dma_error_irq_occurred ++;
DMA_PL230_DMAC->ERR_CLR = 1; /* Clear dma_err */
if (dma_error_irq_expected==0) {
puts ("ERROR : Unexpected DMA error interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
else {
// DMA interrupt is caused by DMA done
dma_done_irq_occurred ++;
if (dma_done_irq_expected==0) {
puts ("ERROR : Unexpected DMA done interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
}
void EXP0_Handler(void)
{
// AES128 interrupt is caused by Key buffer empty IRQ
aes_key_irq_occurred ++;
AES128->IRQ_MSK_CLR = AES128_KEY_REQ_BIT;
if (aes_key_irq_expected==0) {
puts ("ERROR : Unexpected AES128 Key buffer empty request interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
void EXP1_Handler(void)
{
// AES128 interrupt is caused by Input buffer empty IRQ
aes_ip_irq_occurred ++;
AES128->IRQ_MSK_CLR = AES128_IP_REQ_BIT;
if (aes_ip_irq_expected==0) {
puts ("ERROR : Unexpected AES128 Input buffer empty reqest interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
void EXP2_Handler(void)
{
// AES128 interrupt is caused by Output buffer full IRQ
aes_op_irq_occurred ++;
AES128->IRQ_MSK_CLR = AES128_OP_REQ_BIT;
if (aes_op_irq_expected==0) {
puts ("ERROR : Unexpected AES128 Output buffer full reqest interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
void EXP3_Handler(void)
{
// AES128 interrupt is caused by Error IRQ
aes_err_irq_occurred ++;
AES128->IRQ_MSK_CLR = AES128_ERR_REQ_BIT;
if (aes_err_irq_expected==0) {
puts ("ERROR : Unexpected AES128 Error interrupt occurred.\n");
UartEndSimulation();
while (1);
}
}
#include <stdio.h>
#include <string.h>
#include "dma_pl230_driver.h"
#define DEBUG_PRINTF(...) do {} while(0);
//#define cpu_to_be32(__x) __x
//#define be32_to_cpu(__x) __x
#ifdef __cplusplus
extern "C" {
#endif
static int g_dma_pl230_initialised = 0;
static dma_pl230_data_structure priv_dma __attribute__((aligned(256)));
//
dma_pl230_data_structure *dma_pl230_table = &priv_dma;
/* --------------------------------------------------------------- */
/* Initialize DMA data structure */
/* --------------------------------------------------------------- */
void dma_pl230_data_struct_init(void)
{
int i; /* loop counter */
// printf ("dma structure block address = %x\n", dma_pl230_table);
for (i=0; i<MAX_NUM_OF_DMA_CHANNELS; i++) {
dma_pl230_table->Primary[i].SrcEndPointer = 0;
dma_pl230_table->Primary[i].DstEndPointer = 0;
dma_pl230_table->Primary[i].Control = 0;
dma_pl230_table->Alternate[i].SrcEndPointer = 0;
dma_pl230_table->Alternate[i].DstEndPointer = 0;
dma_pl230_table->Alternate[i].Control = 0;
}
g_dma_pl230_initialised = 1;
return;
}
void dma_pl230_data_struct_init_dbg(void)
{
int i; /* loop counter */
unsigned int ptr;
int ch_num; /* number of channels */
unsigned int blksize; /* Size of DMA data structure in bytes */
unsigned int blkmask; /* address mask */
ch_num = (((DMA_PL230_DMAC->DMA_STATUS) >> 16) & 0x1F)+1;
blksize = ch_num * 32;
if (ch_num > 16) blkmask = 0x3FF; /* 17 to 32 */
else if (ch_num > 8) blkmask = 0x1FF; /* 9 to 16 */
else if (ch_num > 4) blkmask = 0x0FF; /* 5 to 8 */
else if (ch_num > 2) blkmask = 0x07F; /* 3 to 4 */
else if (ch_num > 1) blkmask = 0x03F; /* 2 */
else blkmask = 0x01F; /* 1 */
/* Create DMA data structure in RAM after stack
In the linker script, a 1KB memory stack above stack is reserved
so we can use this space for putting the DMA data structure.
*/
// ptr = HW32_REG(0); /* Read Top of Stack */
ptr = (0x80000000); // force for now as no reserved RAM available
/* the DMA data structure must be aligned to the size of the data structure */
if ((ptr & blkmask) != 0x0)
ptr = (ptr + blksize) & ~blkmask;
/// if ((ptr + blksize) > (RAM_ADDRESS_MAX + 1)) {
/// puts ("ERROR : Not enough RAM space for DMA data structure.");
/// UartEndSimulation();
/// }
/* Set pointer to the reserved space */
dma_pl230_table = (dma_pl230_data_structure *) ptr;
ptr = (unsigned long) &(dma_pl230_table->Primary[0].SrcEndPointer);
printf ("dma structure block address = %x\n", ptr);
for (i=0; i<MAX_NUM_OF_DMA_CHANNELS; i++) {
dma_pl230_table->Primary[i].SrcEndPointer = 0;
dma_pl230_table->Primary[i].DstEndPointer = 0;
dma_pl230_table->Primary[i].Control = 0;
dma_pl230_table->Alternate[i].SrcEndPointer = 0;
dma_pl230_table->Alternate[i].DstEndPointer = 0;
dma_pl230_table->Alternate[i].Control = 0;
}
g_dma_pl230_initialised = 1;
return;
}
/* --------------------------------------------------------------- */
/* Initialize DMA PL230 */
/* --------------------------------------------------------------- */
void dma_pl230_init_dbg(unsigned int chan_mask)
{
unsigned int current_state;
puts ("Initialize PL230");
current_state = DMA_PL230_DMAC->DMA_STATUS;
printf ("- # of channels allowed : %d\n",(((current_state) >> 16) & 0x1F)+1);
/* Debugging printfs: */
printf ("- Current status : %x\n",(((current_state) >> 4) & 0xF));
printf ("- Current master enable : %x\n",(((current_state) >> 0) & 0x1));
/* Wait until current DMA complete */
current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4) & 0xF;
if (!((current_state==0) || (current_state==0x8) || (current_state==0x9))) {
puts ("- wait for DMA IDLE/STALLED/DONE");
current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4) & 0xF;
printf ("- Current status : %x\n",(((current_state) >> 4) & 0xF));
}
while (!((current_state==0) || (current_state==0x8) || (current_state==0x9))){
/* Wait if not IDLE/STALLED/DONE */
current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4) & 0xF;
printf ("- Current status : %x\n",(((current_state) >> 4) & 0xF));
}
DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
DMA_PL230_DMAC->CTRL_BASE_PTR = (unsigned long) &(dma_pl230_table->Primary->SrcEndPointer);
/* Set DMA data structure address */
DMA_PL230_DMAC->CHNL_ENABLE_CLR = 0xFFFFFFFF; /* Disable all channels */
DMA_PL230_DMAC->CHNL_PRI_ALT_CLR = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all alt channels */
DMA_PL230_DMAC->CHNL_ENABLE_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable channel */
DMA_PL230_DMAC->CHNL_USEBURST_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable bursts */
if (chan_mask)
DMA_PL230_DMAC->DMA_CFG = 1; /* Enable DMA controller if enabled channel*/
return;
}
void dma_pl230_init(unsigned int chan_mask)
{
unsigned int current_state;
if (g_dma_pl230_initialised ==0)
dma_pl230_data_struct_init();
/* Wait until current DMA complete */
current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4) & 0xF;
while (!((current_state==0) || (current_state==0x8) || (current_state==0x9))){
/* Wait if not IDLE/STALLED/DONE */
puts ("- wait for DMA IDLE/STALLED/DONE");
current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4) & 0xF;
}
DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
DMA_PL230_DMAC->CTRL_BASE_PTR = (unsigned long) &(dma_pl230_table->Primary->SrcEndPointer);
/* Set DMA data structure address */
DMA_PL230_DMAC->CHNL_ENABLE_CLR = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all channels */
DMA_PL230_DMAC->CHNL_PRI_ALT_CLR = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all alt channels */
DMA_PL230_DMAC->CHNL_ENABLE_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable channel */
DMA_PL230_DMAC->CHNL_USEBURST_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable bursts */
g_dma_pl230_initialised = 2;
if (chan_mask)
DMA_PL230_DMAC->DMA_CFG = 1; /* Enable DMA controller if enabled channel*/
return;
}
unsigned int dma_pl230_channel_active(unsigned int chan_mask)
{
return(DMA_PL230_DMAC->CHNL_ENABLE_SET & chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enabled channels */
}
#ifdef __cplusplus
}
#endif
#ifndef __DMA_PL230_MCU_H
#define __DMA_PL230_MCU_H
#ifdef __cplusplus
extern "C" {
#endif
#include "CMSDK_CM0.h"
#define DMA_PL230_BASE (CMSDK_APB_BASE + 0xF000UL)
#define MAX_NUM_OF_DMA_CHANNELS 2
/*------------- PL230 uDMA (PL230) --------------------------------------*/
/** @addtogroup DMA_PL230 CMSDK uDMA controller
@{
*/
typedef struct
{
__I uint32_t DMA_STATUS; /*!< Offset: 0x000 DMA status Register (R/W) */
__O uint32_t DMA_CFG; /*!< Offset: 0x004 DMA configuration Register ( /W) */
__IO uint32_t CTRL_BASE_PTR; /*!< Offset: 0x008 Channel Control Data Base Pointer Register (R/W) */
__I uint32_t ALT_CTRL_BASE_PTR; /*!< Offset: 0x00C Channel Alternate Control Data Base Pointer Register (R/ ) */
__I uint32_t DMA_WAITONREQ_STATUS; /*!< Offset: 0x010 Channel Wait On Request Status Register (R/ ) */
__O uint32_t CHNL_SW_REQUEST; /*!< Offset: 0x014 Channel Software Request Register ( /W) */
__IO uint32_t CHNL_USEBURST_SET; /*!< Offset: 0x018 Channel UseBurst Set Register (R/W) */
__O uint32_t CHNL_USEBURST_CLR; /*!< Offset: 0x01C Channel UseBurst Clear Register ( /W) */
__IO uint32_t CHNL_REQ_MASK_SET; /*!< Offset: 0x020 Channel Request Mask Set Register (R/W) */
__O uint32_t CHNL_REQ_MASK_CLR; /*!< Offset: 0x024 Channel Request Mask Clear Register ( /W) */
__IO uint32_t CHNL_ENABLE_SET; /*!< Offset: 0x028 Channel Enable Set Register (R/W) */
__O uint32_t CHNL_ENABLE_CLR; /*!< Offset: 0x02C Channel Enable Clear Register ( /W) */
__IO uint32_t CHNL_PRI_ALT_SET; /*!< Offset: 0x030 Channel Primary-Alterante Set Register (R/W) */
__O uint32_t CHNL_PRI_ALT_CLR; /*!< Offset: 0x034 Channel Primary-Alterante Clear Register ( /W) */
__IO uint32_t CHNL_PRIORITY_SET; /*!< Offset: 0x038 Channel Priority Set Register (R/W) */
__O uint32_t CHNL_PRIORITY_CLR; /*!< Offset: 0x03C Channel Priority Clear Register ( /W) */
uint32_t RESERVED0[3];
__IO uint32_t ERR_CLR; /*!< Offset: 0x04C Bus Error Clear Register (R/W) */
} DMA_PL230_TypeDef;
#define PL230_DMA_CHNL_BITS 0
#define DMA_PL230_DMA_STATUS_MSTREN_Pos 0 /*!< DMA_PL230 DMA STATUS: MSTREN Position */
#define DMA_PL230_DMA_STATUS_MSTREN_Msk (0x00000001ul << DMA_PL230_DMA_STATUS_MSTREN_Pos) /*!< DMA_PL230 DMA STATUS: MSTREN Mask */
#define DMA_PL230_DMA_STATUS_STATE_Pos 0 /*!< DMA_PL230 DMA STATUS: STATE Position */
#define DMA_PL230_DMA_STATUS_STATE_Msk (0x0000000Ful << DMA_PL230_DMA_STATUS_STATE_Pos) /*!< DMA_PL230 DMA STATUS: STATE Mask */
#define DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Pos 0 /*!< DMA_PL230 DMA STATUS: CHNLS_MINUS1 Position */
#define DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Msk (0x0000001Ful << DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Pos) /*!< DMA_PL230 DMA STATUS: CHNLS_MINUS1 Mask */
#define DMA_PL230_DMA_STATUS_TEST_STATUS_Pos 0 /*!< DMA_PL230 DMA STATUS: TEST_STATUS Position */
#define DMA_PL230_DMA_STATUS_TEST_STATUS_Msk (0x00000001ul << DMA_PL230_DMA_STATUS_TEST_STATUS_Pos) /*!< DMA_PL230 DMA STATUS: TEST_STATUS Mask */
#define DMA_PL230_DMA_CFG_MSTREN_Pos 0 /*!< DMA_PL230 DMA CFG: MSTREN Position */
#define DMA_PL230_DMA_CFG_MSTREN_Msk (0x00000001ul << DMA_PL230_DMA_CFG_MSTREN_Pos) /*!< DMA_PL230 DMA CFG: MSTREN Mask */
#define DMA_PL230_DMA_CFG_CPCCACHE_Pos 2 /*!< DMA_PL230 DMA CFG: CPCCACHE Position */
#define DMA_PL230_DMA_CFG_CPCCACHE_Msk (0x00000001ul << DMA_PL230_DMA_CFG_CPCCACHE_Pos) /*!< DMA_PL230 DMA CFG: CPCCACHE Mask */
#define DMA_PL230_DMA_CFG_CPCBUF_Pos 1 /*!< DMA_PL230 DMA CFG: CPCBUF Position */
#define DMA_PL230_DMA_CFG_CPCBUF_Msk (0x00000001ul << DMA_PL230_DMA_CFG_CPCBUF_Pos) /*!< DMA_PL230 DMA CFG: CPCBUF Mask */
#define DMA_PL230_DMA_CFG_CPCPRIV_Pos 0 /*!< DMA_PL230 DMA CFG: CPCPRIV Position */
#define DMA_PL230_DMA_CFG_CPCPRIV_Msk (0x00000001ul << DMA_PL230_DMA_CFG_CPCPRIV_Pos) /*!< DMA_PL230 DMA CFG: CPCPRIV Mask */
#define DMA_PL230_CTRL_BASE_PTR_Pos PL230_DMA_CHNL_BITS + 5 /*!< DMA_PL230 STATUS: BASE_PTR Position */
#define DMA_PL230_CTRL_BASE_PTR_Msk (0x0FFFFFFFul << DMA_PL230_CTRL_BASE_PTR_Pos) /*!< DMA_PL230 STATUS: BASE_PTR Mask */
#define DMA_PL230_ALT_CTRL_BASE_PTR_Pos 0 /*!< DMA_PL230 STATUS: MSTREN Position */
#define DMA_PL230_ALT_CTRL_BASE_PTR_Msk (0xFFFFFFFFul << DMA_PL230_ALT_CTRL_BASE_PTR_Pos) /*!< DMA_PL230 STATUS: MSTREN Mask */
#define DMA_PL230_DMA_WAITONREQ_STATUS_Pos 0 /*!< DMA_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Position */
#define DMA_PL230_DMA_WAITONREQ_STATUS_Msk (0xFFFFFFFFul << DMA_PL230_DMA_WAITONREQ_STATUS_Pos) /*!< DMA_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Mask */
#define DMA_PL230_CHNL_SW_REQUEST_Pos 0 /*!< DMA_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Position */
#define DMA_PL230_CHNL_SW_REQUEST_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_SW_REQUEST_Pos) /*!< DMA_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Mask */
#define DMA_PL230_CHNL_USEBURST_SET_Pos 0 /*!< DMA_PL230 CHNL_USEBURST: SET Position */
#define DMA_PL230_CHNL_USEBURST_SET_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_USEBURST_SET_Pos) /*!< DMA_PL230 CHNL_USEBURST: SET Mask */
#define DMA_PL230_CHNL_USEBURST_CLR_Pos 0 /*!< DMA_PL230 CHNL_USEBURST: CLR Position */
#define DMA_PL230_CHNL_USEBURST_CLR_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_USEBURST_CLR_Pos) /*!< DMA_PL230 CHNL_USEBURST: CLR Mask */
#define DMA_PL230_CHNL_REQ_MASK_SET_Pos 0 /*!< DMA_PL230 CHNL_REQ_MASK: SET Position */
#define DMA_PL230_CHNL_REQ_MASK_SET_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_REQ_MASK_SET_Pos) /*!< DMA_PL230 CHNL_REQ_MASK: SET Mask */
#define DMA_PL230_CHNL_REQ_MASK_CLR_Pos 0 /*!< DMA_PL230 CHNL_REQ_MASK: CLR Position */
#define DMA_PL230_CHNL_REQ_MASK_CLR_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_REQ_MASK_CLR_Pos) /*!< DMA_PL230 CHNL_REQ_MASK: CLR Mask */
#define DMA_PL230_CHNL_ENABLE_SET_Pos 0 /*!< DMA_PL230 CHNL_ENABLE: SET Position */
#define DMA_PL230_CHNL_ENABLE_SET_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_ENABLE_SET_Pos) /*!< DMA_PL230 CHNL_ENABLE: SET Mask */
#define DMA_PL230_CHNL_ENABLE_CLR_Pos 0 /*!< DMA_PL230 CHNL_ENABLE: CLR Position */
#define DMA_PL230_CHNL_ENABLE_CLR_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_ENABLE_CLR_Pos) /*!< DMA_PL230 CHNL_ENABLE: CLR Mask */
#define DMA_PL230_CHNL_PRI_ALT_SET_Pos 0 /*!< DMA_PL230 CHNL_PRI_ALT: SET Position */
#define DMA_PL230_CHNL_PRI_ALT_SET_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_PRI_ALT_SET_Pos) /*!< DMA_PL230 CHNL_PRI_ALT: SET Mask */
#define DMA_PL230_CHNL_PRI_ALT_CLR_Pos 0 /*!< DMA_PL230 CHNL_PRI_ALT: CLR Position */
#define DMA_PL230_CHNL_PRI_ALT_CLR_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_PRI_ALT_CLR_Pos) /*!< DMA_PL230 CHNL_PRI_ALT: CLR Mask */
#define DMA_PL230_CHNL_PRIORITY_SET_Pos 0 /*!< DMA_PL230 CHNL_PRIORITY: SET Position */
#define DMA_PL230_CHNL_PRIORITY_SET_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_PRIORITY_SET_Pos) /*!< DMA_PL230 CHNL_PRIORITY: SET Mask */
#define DMA_PL230_CHNL_PRIORITY_CLR_Pos 0 /*!< DMA_PL230 CHNL_PRIORITY: CLR Position */
#define DMA_PL230_CHNL_PRIORITY_CLR_Msk (0xFFFFFFFFul << DMA_PL230_CHNL_PRIORITY_CLR_Pos) /*!< DMA_PL230 CHNL_PRIORITY: CLR Mask */
#define DMA_PL230_ERR_CLR_Pos 0 /*!< DMA_PL230 ERR: CLR Position */
#define DMA_PL230_ERR_CLR_Msk (0x00000001ul << DMA_PL230_ERR_CLR_Pos) /*!< DMA_PL230 ERR: CLR Mask */
#define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS)))
/* Maximum to 32 DMA channel */
/* SRAM in example system is 64K bytes */
#define RAM_ADDRESS_MAX 0x80001fff
typedef struct /* 4 words */
{
volatile unsigned char* SrcEndPointer;
volatile unsigned char* DstEndPointer;
volatile unsigned long Control;
volatile unsigned long unused;
} dma_pl230_channel_data;
typedef struct /* 8 words per channel */
{ /* was one channel in the example uDMA setup */
volatile dma_pl230_channel_data Primary[MAX_NUM_OF_DMA_CHANNELS];
volatile dma_pl230_channel_data Alternate[MAX_NUM_OF_DMA_CHANNELS];
} dma_pl230_data_structure;
extern dma_pl230_data_structure *dma_pl230_table;
#define DMA_PL230_DMAC ((DMA_PL230_TypeDef *) DMA_PL230_BASE)
#define DMA_PL230_PTR_END(__ptr, __siz, __num) \
((unsigned char *) __ptr + ((1<<__siz)*(__num-1)))
#define DMA_PL230_CTRL(__cyc, __siz, __num, __rpwr) \
(((unsigned long) __siz << 30)|(__siz << 28)|(__siz << 26)|(__siz << 24)| \
(1 << 21)|(1 << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
(1 << 3)|(__cyc << 0) )
#define DMA_PL230_CTRL_SRCFIX(__cyc, __siz, __num, __rpwr) \
(((unsigned long) __siz << 30)|(__siz << 28)|(0x0c000000UL)|(__siz << 24)| \
(1 << 21)|(1 << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
(1 << 3)|(__cyc << 0) )
#define DMA_PL230_CTRL_DSTFIX(__cyc, __siz, __num, __rpwr) \
((0xc0000000UL)|(__siz << 28)|(__siz << 26)|(__siz << 24)| \
(1 << 21)|(1 << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
(1 << 3)|(__cyc << 0) )
#define DMA_PL230_MAX_XFERS (0x400)
#define PL230_CTRL_CYCLE_STOP 0
#define PL230_CTRL_CYCLE_BASIC 1
#define PL230_CTRL_CYCLE_AUTO 2
#define PL230_CTRL_CYCLE_PPONG 3
#define PL230_CTRL_CYCLE_MEM_CHAIN_PRI 4
#define PL230_CTRL_CYCLE_MEM_CHAIN_ALT 5
#define PL230_CTRL_CYCLE_DEV_CHAIN_PRI 6
#define PL230_CTRL_CYCLE_DEV_CHAIN_ALT 7
#define PL230_CTRL_RPWR_1 0
#define PL230_CTRL_RPWR_2 1
#define PL230_CTRL_RPWR_4 2
#define PL230_CTRL_RPWR_8 3
#define PL230_CTRL_RPWR_16 4
#define PL230_XFER_B 0
#define PL230_XFER_H 1
#define PL230_XFER_W 2
/* --------------------------------------------------------------- */
/* Initialize DMA data structure */
/* --------------------------------------------------------------- */
void dma_pl230_data_struct_init(void);
/* --------------------------------------------------------------- */
/* Initialize DMA PL230 */
/* --------------------------------------------------------------- */
void dma_pl230_init_dbg(unsigned int chan_mask);
void dma_pl230_init(unsigned int chan_mask);
/* --------------------------------------------------------------- */
/* Check DMA PL230 DMA channel(s) active (return 0 when finishes) */
/* --------------------------------------------------------------- */
unsigned int dma_pl230_channel_active(unsigned int chan_mask);
#ifdef __cplusplus
}
#endif
#endif /* __DMA_PL230_MCU_H */
#-----------------------------------------------------------------------------
# The confidential and proprietary information contained in this file may
# only be used by a person authorised under and to the extent permitted
# by a subsisting licensing agreement from Arm Limited or its affiliates.
#
# (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates.
# ALL RIGHTS RESERVED
#
# This entire notice must be reproduced on all copies of this file
# and copies of this file may only be made by a person if such person is
# permitted to do so under the terms of a subsisting license agreement
# from Arm Limited or its affiliates.
#
# SVN Information
#
# Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
#
# Revision : $Revision: 371321 $
#
# Release Information : Cortex-M System Design Kit-r1p1-00rel0
#-----------------------------------------------------------------------------
#
# Cortex-M System Design Kit software compilation make file
#
#-----------------------------------------------------------------------------
#
# Configurations
#
# Choose the core instantiated, can be
# - CORTEX_M0
# - CORTEX_M0PLUS
CPU_PRODUCT = CORTEX_M0
# Shared software directory
SOFTWARE_DIR = $(NANOSOC_TECH_DIR)/software
CMSIS_DIR = $(SOFTWARE_DIR)/cmsis
CORE_DIR = $(CMSIS_DIR)/CMSIS/Include
ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0plus
else
DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0
endif
# Program file
TESTNAME = aes128_tests
# Endian Option
COMPILE_BIGEND = 0
# Configuration
ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
USER_DEFINE = -DCORTEX_M0PLUS
else
USER_DEFINE = -DCORTEX_M0
endif
DEPS_LIST = makefile
# Tool chain : ds5 / gcc / keil
TOOL_CHAIN = ds5
ifeq ($(TOOL_CHAIN),ds5)
ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
CPU_TYPE = --cpu Cortex-M0plus
else
CPU_TYPE = --cpu Cortex-M0
endif
endif
ifeq ($(TOOL_CHAIN),gcc)
ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
CPU_TYPE = -mcpu=cortex-m0plus
else
CPU_TYPE = -mcpu=cortex-m0
endif
endif
# Startup code directory for DS-5
ifeq ($(TOOL_CHAIN),ds5)
STARTUP_DIR = $(DEVICE_DIR)/Source/ARM
endif
# Startup code directory for gcc
ifeq ($(TOOL_CHAIN),gcc)
STARTUP_DIR = $(DEVICE_DIR)/Source/GCC
endif
ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
STARTUP_FILE = startup_CMSDK_CM0plus
SYSTEM_FILE = system_CMSDK_CM0plus
else
STARTUP_FILE = startup_CMSDK_CM0
SYSTEM_FILE = system_CMSDK_CM0
endif
# ---------------------------------------------------------------------------------------
# DS-5 options
# MicroLIB option
COMPILE_MICROLIB = 0
# Small Multiply (Cortex-M0/M0+ has small multiplier option)
COMPILE_SMALLMUL = 0
#ARM_CC_OPTIONS = -c -O3 -g -Otime -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
# -I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE)
#ARM_ASM_OPTIONS = -g
#ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
# --rw_base 0x30000000 --ro_base 0x00000000 --map --info sizes
ARM_CC_OPTIONS = -c -O3 -Ospace -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
-I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE)
ARM_ASM_OPTIONS =
ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
--no_debug --rw_base 0x30000000 --ro_base 0x00000000 --map --info sizes
ifeq ($(COMPILE_BIGEND),1)
# Big Endian
ARM_CC_OPTIONS += --bigend
ARM_ASM_OPTIONS += --bigend
ARM_LINK_OPTIONS += --be8
endif
ifeq ($(COMPILE_MICROLIB),1)
# MicroLIB
ARM_CC_OPTIONS += --library_type=microlib
ARM_ASM_OPTIONS += --library_type=microlib --pd "__MICROLIB SETA 1"
ARM_LINK_OPTIONS += --library_type=microlib
endif
ifeq ($(COMPILE_SMALLMUL),1)
# In Cortex-M0, small multiply takes 32 cycles
ARM_CC_OPTIONS += --multiply_latency=32
endif
# ---------------------------------------------------------------------------------------
# gcc options
GNG_CC = arm-none-eabi-gcc
GNU_OBJDUMP = arm-none-eabi-objdump
GNU_OBJCOPY = arm-none-eabi-objcopy
LINKER_SCRIPT_PATH = $(SOFTWARE_DIR)/common/scripts
LINKER_SCRIPT = $(LINKER_SCRIPT_PATH)/cmsdk_cm0.ld
GNU_CC_FLAGS = -g -O3 -mthumb $(CPU_TYPE)
ifeq ($(COMPILE_BIGEND),1)
# Big Endian
GNU_CC_FLAGS += -mbig-endian
endif
# ---------------------------------------------------------------------------------------
all: all_$(TOOL_CHAIN)
# ---------------------------------------------------------------------------------------
# DS-5
all_ds5 : $(TESTNAME).hex $(TESTNAME).lst $(TESTNAME).bin
$(TESTNAME).o : $(TESTNAME).c $(DEPS_LIST)
armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
dma_pl230_driver.o : dma_pl230_driver.c $(DEPS_LIST)
armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
$(SYSTEM_FILE).o : $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c $(DEPS_LIST)
armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
retarget.o : $(SOFTWARE_DIR)/common/retarget/retarget.c $(DEPS_LIST)
armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
uart_stdout.o : $(SOFTWARE_DIR)/common/retarget/uart_stdout.c $(DEPS_LIST)
armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
$(STARTUP_FILE).o : $(STARTUP_DIR)/$(STARTUP_FILE).s $(DEPS_LIST)
armasm $(ARM_ASM_OPTIONS) $(CPU_TYPE) $< -o $@
$(TESTNAME).ELF : $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o
armlink $(ARM_LINK_OPTIONS) -o $@ $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o
$(TESTNAME).hex : $(TESTNAME).ELF
fromelf --vhx --8x1 $< --output $@
fromelf --vhx --8x1 $< --output ../../image.hex
$(TESTNAME).lst : $(TESTNAME).ELF
fromelf -c -d -e -s -z -v $< --output $@
$(TESTNAME).bin : $(TESTNAME).ELF
fromelf --bin $< --output $@
# ---------------------------------------------------------------------------------------
# gcc
all_gcc:
$(GNG_CC) $(GNU_CC_FLAGS) $(STARTUP_DIR)/$(STARTUP_FILE).s \
$(TESTNAME).c \
$(SOFTWARE_DIR)/common/retarget/retarget.c \
$(SOFTWARE_DIR)/common/retarget/uart_stdout.c \
$(DEVICE_DIR)/Source/$(SYSTEM_FILE).c \
-I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
-I $(SOFTWARE_DIR)/common/retarget \
-L $(LINKER_SCRIPT_PATH) \
-D__STACK_SIZE=0x200 \
-D__HEAP_SIZE=0x1000 \
$(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(TESTNAME).o
# Generate disassembly code
$(GNU_OBJDUMP) -S $(TESTNAME).o > $(TESTNAME).lst
# Generate binary file
$(GNU_OBJCOPY) -S $(TESTNAME).o -O binary $(TESTNAME).bin
# Generate hex file
$(GNU_OBJCOPY) -S $(TESTNAME).o -O verilog $(TESTNAME).hex
# Note:
# If the version of object copy you are using does not support verilog hex file output,
# you can generate the hex file from binary file using the following command
# od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex
# ---------------------------------------------------------------------------------------
# Keil MDK
all_keil:
@echo "Please compile your project code and press ENTER when ready"
@read dummy
# ---------------------------------------------------------------------------------------
# Binary
all_bin: $(TESTNAME).bin
# Generate hex file from binary
od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex
# ---------------------------------------------------------------------------------------
# Clean
clean :
@rm -rf *.o
@if [ -e $(TESTNAME).hex ] ; then \
rm -rf $(TESTNAME).hex ; \
fi
@if [ -e $(TESTNAME).lst ] ; then \
rm -rf $(TESTNAME).lst ; \
fi
@if [ -e $(TESTNAME).ELF ] ; then \
rm -rf $(TESTNAME).ELF ; \
fi
@if [ -e $(TESTNAME).bin ] ; then \
rm -rf $(TESTNAME).bin ; \
fi
@rm -rf *.crf
@rm -rf *.plg
@rm -rf *.tra
@rm -rf *.htm
@rm -rf *.map
@rm -rf *.dep
@rm -rf *.d
@rm -rf *.lnp
@rm -rf *.bak
@rm -rf *.lst
@rm -rf *.axf
@rm -rf *.sct
@rm -rf *.__i
@rm -rf *._ia
......@@ -37,6 +37,8 @@
//
`timescale 1ns/1ps
`define CORTEX_M0
module nanosoc_tb;
wire XTAL1; // crystal pin 1
......@@ -229,7 +231,7 @@ reg baud_clk_del;
wire uart_clk = (FASTMODE) ? PCLK : baud_clk; //(baud_clk & !baud_clk_del);
nanosoc_uart_capture #(.LOGFILENAME("uart2.log"))
nanosoc_uart_capture #(.LOGFILENAME("logs/uart2.log"))
u_nanosoc_uart_capture(
.RESETn (NRST),
.CLK (uart_clk), //PCLK),
......@@ -317,7 +319,7 @@ nanosoc_ft1248x1_to_axi_streamio_v1_0
);
nanosoc_axi_stream_io_8_rxd_to_file
#(.RXDFILENAME("ft1248_out.log"))
#(.RXDFILENAME("logs/ft1248_out.log"))
u_nanosoc_axi_stream_io_8_rxd_to_file
(
.aclk (XTAL1),
......@@ -358,7 +360,7 @@ nanosoc_ft1248x1_track
.FTDI_IP2UART_o (ft_txd2uart) // Transmitted data to UART capture
);
nanosoc_uart_capture #(.LOGFILENAME("ft1248_op.log"))
nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_op.log"))
u_nanosoc_uart_capture1(
.RESETn (NRST),
.CLK (ft_clk2uart),
......@@ -368,7 +370,7 @@ nanosoc_ft1248x1_track
.AUXCTRL ()
);
nanosoc_uart_capture #(.LOGFILENAME("ft1248_ip.log"))
nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_ip.log"))
u_nanosoc_uart_capture2(
.RESETn (NRST),
.CLK (ft_clk2uart),
......@@ -453,7 +455,7 @@ nanosoc_ft1248x1_track
.SE (`ARM_CM0IK_PATH.SE));
`define ARM_CM0IK_TRACK u_cortexm0_track
cm0_tarmac #(.LOGFILENAME("tarmac0.log"))
cm0_tarmac #(.LOGFILENAME("logs/tarmac0.log"))
u_tarmac_track
(.enable_i (1'b1),
......@@ -559,7 +561,7 @@ nanosoc_ft1248x1_track
`define DMAC_TRACK_PATH u_track_pl230_udma
nanosoc_dma_log_to_file #(.FILENAME("dma230.log"),.NUM_CHNLS(2),.NUM_CHNL_BITS(1),.TIMESTAMP(1))
nanosoc_dma_log_to_file #(.FILENAME("logs/dma230.log"),.NUM_CHNLS(2),.NUM_CHNL_BITS(1),.TIMESTAMP(1))
u_nanosoc_dma_log_to_file (
.hclk (`DMAC_TRACK_PATH.hclk),
.hresetn (`DMAC_TRACK_PATH.hresetn),
......@@ -595,33 +597,33 @@ nanosoc_ft1248x1_track
// Tracking AES logging support
// --------------------------------------------------------------------------------
// `define AES_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_exp_aes128
// aes128_log_to_file #(.FILENAME("aes128.log"),.TIMESTAMP(1))
// u_aes_log_to_file (
// .ahb_hclk (`AES_PATH.ahb_hclk ),
// .ahb_hresetn (`AES_PATH.ahb_hresetn ),
// .ahb_hsel (`AES_PATH.ahb_hsel ),
// .ahb_haddr16 (`AES_PATH.ahb_haddr16 ),
// .ahb_htrans (`AES_PATH.ahb_htrans ),
// .ahb_hwrite (`AES_PATH.ahb_hwrite ),
// .ahb_hsize (`AES_PATH.ahb_hsize ),
// .ahb_hprot (`AES_PATH.ahb_hprot ),
// .ahb_hwdata (`AES_PATH.ahb_hwdata ),
// .ahb_hready (`AES_PATH.ahb_hready ),
// .ahb_hrdata (`AES_PATH.ahb_hrdata ),
// .ahb_hreadyout (`AES_PATH.ahb_hreadyout ),
// .ahb_hresp (`AES_PATH.ahb_hresp ),
// .drq_ipdma128 (`AES_PATH.drq_ipdma128 ),
// .dlast_ipdma128 (`AES_PATH.dlast_ipdma128),
// .drq_opdma128 (`AES_PATH.drq_opdma128 ),
// .dlast_opdma128 (`AES_PATH.dlast_opdma128),
// .irq_key128 (`AES_PATH.irq_key128 ),
// .irq_ip128 (`AES_PATH.irq_ip128 ),
// .irq_op128 (`AES_PATH.irq_op128 ),
// .irq_error (`AES_PATH.irq_error ),
// .irq_merged (`AES_PATH.irq_merged )
// );
`define AES_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_nanosoc_exp_wrapper.u_exp_aes128
aes128_log_to_file #(.FILENAME("logs/aes128.log"),.TIMESTAMP(1))
u_aes_log_to_file (
.ahb_hclk (`AES_PATH.ahb_hclk ),
.ahb_hresetn (`AES_PATH.ahb_hresetn ),
.ahb_hsel (`AES_PATH.ahb_hsel ),
.ahb_haddr16 (`AES_PATH.ahb_haddr16 ),
.ahb_htrans (`AES_PATH.ahb_htrans ),
.ahb_hwrite (`AES_PATH.ahb_hwrite ),
.ahb_hsize (`AES_PATH.ahb_hsize ),
.ahb_hprot (`AES_PATH.ahb_hprot ),
.ahb_hwdata (`AES_PATH.ahb_hwdata ),
.ahb_hready (`AES_PATH.ahb_hready ),
.ahb_hrdata (`AES_PATH.ahb_hrdata ),
.ahb_hreadyout (`AES_PATH.ahb_hreadyout ),
.ahb_hresp (`AES_PATH.ahb_hresp ),
.drq_ipdma128 (`AES_PATH.drq_ipdma128 ),
.dlast_ipdma128 (`AES_PATH.dlast_ipdma128),
.drq_opdma128 (`AES_PATH.drq_opdma128 ),
.dlast_opdma128 (`AES_PATH.dlast_opdma128),
.irq_key128 (`AES_PATH.irq_key128 ),
.irq_ip128 (`AES_PATH.irq_ip128 ),
.irq_op128 (`AES_PATH.irq_op128 ),
.irq_error (`AES_PATH.irq_error ),
.irq_merged (`AES_PATH.irq_merged )
);
// --------------------------------------------------------------------------------
......