Select Git revision
aes128_log_to_file.v 13.01 KiB
//-----------------------------------------------------------------------------
// AHB transaction logger, developed for DMA integration testing
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Flynn (d.w.flynn@soton.ac.uk)
//
// Copyright (C) 2023, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
module aes128_log_to_file
#(parameter FILENAME = "aes128.log",
parameter TIMESTAMP = 1)
(
input wire ahb_hclk, // Clock
input wire ahb_hresetn, // Reset
input wire ahb_hsel, // Device select
input wire [15:0] ahb_haddr16, // Address for byte select
input wire [1:0] ahb_htrans, // Transfer control
input wire [2:0] ahb_hsize, // Transfer size
input wire [3:0] ahb_hprot, // Protection control
input wire ahb_hwrite, // Write control
input wire ahb_hready, // Transfer phase done
input wire [31:0] ahb_hwdata, // Write data
input wire ahb_hreadyout, // Device ready
input wire [31:0] ahb_hrdata, // Read data output
input wire ahb_hresp, // Device response
// stream data
input wire drq_ipdma128, // (to) DMAC input burst request
input wire dlast_ipdma128,// (from) DMAC input burst end (last transfer)
input wire drq_opdma128, // (to) DMAC output dma burst request
input wire dlast_opdma128,// (from) DMAC output burst end (last transfer)
input wire irq_key128,
input wire irq_ip128,
input wire irq_op128,
input wire irq_error,
input wire irq_merged // combined interrrupt request (to CPU)
);
// CORE ID
localparam ADDR_CORE_NAME0 = 16'h0000;
localparam ADDR_CORE_NAME1 = 16'h0004;
localparam ADDR_CORE_VERSION= 16'h0008;
localparam CORE_NAME0 = 32'h61657331; // "aes1"
localparam CORE_NAME1 = 32'h32382020; // "28 "
localparam CORE_VERSION = 32'h302e3031; // "0.01"
// CTRL control register with bit-set/bit-clear options
localparam ADDR_CTRL = 16'h0010;
localparam ADDR_CTRL_SET = 16'h0014;
localparam ADDR_CTRL_CLR = 16'h0018;
localparam CTRL_REG_WIDTH = 8;
localparam CTRL_BIT_MAX = (CTRL_REG_WIDTH-1);
localparam CTRL_KEY_REQ_BIT = 0;
localparam CTRL_IP_REQ_BIT = 1;
localparam CTRL_OP_REQ_BIT = 2;
localparam CTRL_ERR_REQ_BIT = 3;
localparam CTRL_KEYOK_BIT = 4;
localparam CTRL_VALID_BIT = 5;
localparam CTRL_BYPASS_BIT = 6;
localparam CTRL_ENCODE_BIT = 7;
// STAT status regisyer
localparam ADDR_STAT = 16'h001c;
localparam STAT_REG_WIDTH = 8;
localparam STAT_BIT_MAX = (STAT_REG_WIDTH-1);
localparam STAT_KEYREQ_BIT = 0;
localparam STAT_INPREQ_BIT = 1;
localparam STAT_OUTREQ_BIT = 2;
localparam STAT_ERROR_BIT = 3;
localparam STAT_KEYOK_BIT = 4;
localparam STAT_VALID_BIT = 5;
// QUAL qualifier field
localparam ADDR_QUAL = 16'h0020;
localparam QUAL_REG_WIDTH = 32;
localparam QUAL_BIT_MAX = (QUAL_REG_WIDTH-1);
// DREQ DMAC request control with bit-set/bit-clear options
localparam ADDR_DREQ = 16'h0030;
localparam ADDR_DREQ_SET = 16'h0034;
localparam ADDR_DREQ_CLR = 16'h0038;
localparam ADDR_DREQ_ACT = 16'h003c;
localparam DREQ_REG_WIDTH = 3;
localparam DREQ_BIT_MAX = (DREQ_REG_WIDTH-1);
localparam REQ_KEYBUF_BIT = 0;
localparam REQ_IP_BUF_BIT = 1;
localparam REQ_OP_BUF_BIT = 2;
// IREQ CPU interrupt request control with bit-set/bit-clear options
localparam ADDR_IREQ = 16'h0040;
localparam ADDR_IREQ_SET = 16'h0044;
localparam ADDR_IREQ_CLR = 16'h0048;
localparam ADDR_IREQ_ACT = 16'h004c;
localparam IREQ_REG_WIDTH = 4;
localparam IREQ_BIT_MAX = (IREQ_REG_WIDTH-1);
localparam REQ_ERROR_BIT = 3;
localparam ADDR_KEY_BASE = 16'h4000;
localparam ADDR_KEY0 = 16'h4000;
localparam ADDR_KEY3 = 16'h400c;
localparam ADDR_KEY7 = 16'h401c;
localparam ADDR_IBUF_BASE = 16'h8000;
localparam ADDR_IBUF_0 = 16'h8000;
localparam ADDR_IBUF_3 = 16'h800c;
localparam ADDR_OBUF_BASE = 16'hc000;
localparam ADDR_OBUF_3 = 16'hc00c;
// AHB transction de-pipelining
// --------------------------------------------------------------------------
// Internal regs/wires
// --------------------------------------------------------------------------
reg sel_r;
reg [15:0] addr16_r;
reg wcyc_r;
reg rcyc_r;
reg [3:0] byte4_r;
reg [3:0] dma_ctrl_state_r;
// --------------------------------------------------------------------------
// AHB slave byte buffer interface, support for unaligned data transfers
// --------------------------------------------------------------------------
wire [1:0] byte_addr = ahb_haddr16[1:0];
// generate next byte enable decodes for Word/Half/Byte CPU/DMA accesses
wire [3:0] byte_nxt;
assign byte_nxt[0] = (ahb_hsize[1])|((ahb_hsize[0])&(!byte_addr[1]))|(byte_addr[1:0]==2'b00);
assign byte_nxt[1] = (ahb_hsize[1])|((ahb_hsize[0])&(!byte_addr[1]))|(byte_addr[1:0]==2'b01);
assign byte_nxt[2] = (ahb_hsize[1])|((ahb_hsize[0])&( byte_addr[1]))|(byte_addr[1:0]==2'b10);
assign byte_nxt[3] = (ahb_hsize[1])|((ahb_hsize[0])&( byte_addr[1]))|(byte_addr[1:0]==2'b11);
// de-pipelined registered access signals
always @(posedge ahb_hclk or negedge ahb_hresetn)
if (!ahb_hresetn)
begin
addr16_r <= 16'h0000;
sel_r <= 1'b0;
wcyc_r <= 1'b0;
rcyc_r <= 1'b0;
byte4_r <= 4'b0000;
end else if (ahb_hready)
begin
addr16_r <= (ahb_hsel & ahb_htrans[1]) ? ahb_haddr16 : addr16_r;
sel_r <= (ahb_hsel & ahb_htrans[1]);
wcyc_r <= (ahb_hsel & ahb_htrans[1] & ahb_hwrite);
rcyc_r <= (ahb_hsel & ahb_htrans[1] & !ahb_hwrite);
byte4_r <= (ahb_hsel & ahb_htrans[1]) ? byte_nxt[3:0] : 4'b0000;
end
wire [31:0] ahb_hdata = (wcyc_r)? ahb_hwdata : ahb_hrdata;
//----------------------------------------------
//-- File I/O
//----------------------------------------------
integer fd; // channel descriptor for cmd file input
integer ch;
reg drq_ipdma128_prev;
reg dlast_ipdma128_prev;
reg drq_opdma128_prev;
reg dlast_opdma128_prev;
reg irq_key128_prev;
reg irq_ip128_prev;
reg irq_op128_prev;
reg irq_error_prev;
reg irq_merged_prev;
wire drq_ipdma128_change;
wire dlast_ipdma128_change;
wire drq_opdma128_change;
wire dlast_opdma128_change;
wire irq_key128_change;
wire irq_ip128_change;
wire irq_op128_change;
wire irq_error_change;
wire irq_merged_change;
wire irq_change;
wire drq_change;
wire any_change;
reg [31:0] cyc_count;
`define EOF -1
reg [7:0] ctrl_reg;
reg [2:0] dreq_reg;
reg [2:0] ireq_reg;
always @(posedge ahb_hclk or negedge ahb_hresetn)
if (!ahb_hresetn)
begin
drq_ipdma128_prev <= 1'b0;
dlast_ipdma128_prev <= 1'b0;
drq_opdma128_prev <= 1'b0;
dlast_opdma128_prev <= 1'b0;
irq_key128_prev <= 1'b0;
irq_ip128_prev <= 1'b0;
irq_op128_prev <= 1'b0;
irq_error_prev <= 1'b0;
irq_merged_prev <= 1'b0;
end else if (ahb_hready)
begin
drq_ipdma128_prev <= drq_ipdma128 ;
dlast_ipdma128_prev <= dlast_ipdma128;
drq_opdma128_prev <= drq_opdma128 ;
dlast_opdma128_prev <= dlast_opdma128;
irq_key128_prev <= irq_key128 ;
irq_ip128_prev <= irq_ip128 ;
irq_op128_prev <= irq_op128 ;
irq_error_prev <= irq_error ;
irq_merged_prev <= irq_merged ;
end
assign drq_ipdma128_change = (drq_ipdma128_prev ^ drq_ipdma128 );
assign dlast_ipdma128_change = (dlast_ipdma128_prev ^ dlast_ipdma128);
assign drq_opdma128_change = (drq_opdma128_prev ^ drq_opdma128 );
assign dlast_opdma128_change = (dlast_opdma128_prev ^ dlast_opdma128);
assign drq_change = drq_ipdma128_change | drq_opdma128_change
| dlast_ipdma128_change | dlast_opdma128_change;
assign irq_key128_change = (irq_key128_prev ^ irq_key128 );
assign irq_ip128_change = (irq_ip128_prev ^ irq_ip128 );
assign irq_op128_change = (irq_op128_prev ^ irq_op128 );
assign irq_error_change = (irq_error_prev ^ irq_error );
assign irq_change = irq_key128_change | irq_ip128_change
| irq_op128_change | irq_error_change;
assign any_change = drq_ipdma128_change
| dlast_ipdma128_change
| drq_opdma128_change
| dlast_opdma128_change
| irq_key128_change
| irq_ip128_change
| irq_op128_change
| irq_error_change
| irq_merged_change
;
initial
begin
fd= $fopen(FILENAME,"w");
cyc_count <= 0;
if (fd == 0)
$write("** %m : output log file failed to open **\n");
else begin
@(posedge ahb_hresetn);
while (1) begin
@(posedge ahb_hclk);
cyc_count <= cyc_count +1;
if (sel_r & ahb_hready) begin
$fwrite(fd, "AES-C: ");
case ({addr16_r[15:2],2'b00})
ADDR_CORE_NAME0 : begin $fwrite(fd, "CORE_NAME0 "); end
ADDR_CORE_NAME1 : begin $fwrite(fd, "CORE_NAME1 "); end
ADDR_CORE_VERSION : begin $fwrite(fd, "CORE_VERSION"); end
ADDR_CTRL : begin $fwrite(fd, "CTRL "); if (wcyc_r) ctrl_reg <= ahb_hwdata[7:0]; end
ADDR_CTRL_SET : begin $fwrite(fd, "CTRL_SET "); if (wcyc_r) ctrl_reg <= ctrl_reg | ahb_hwdata[7:0]; end
ADDR_CTRL_CLR : begin $fwrite(fd, "CTRL_CLR "); if (wcyc_r) ctrl_reg <= ctrl_reg &~ahb_hwdata[7:0]; end
ADDR_STAT : begin $fwrite(fd, "STAT "); end
ADDR_QUAL : begin $fwrite(fd, "QUAL "); end
ADDR_DREQ : begin $fwrite(fd, "DREQ "); if (wcyc_r) dreq_reg <= ahb_hwdata[2:0]; end
ADDR_DREQ_SET : begin $fwrite(fd, "DREQ_SET "); if (wcyc_r) dreq_reg <= dreq_reg | ahb_hwdata[2:0]; end
ADDR_DREQ_CLR : begin $fwrite(fd, "DREQ_CLR "); if (wcyc_r) dreq_reg <= dreq_reg &~ahb_hwdata[2:0]; end
ADDR_DREQ_ACT : begin $fwrite(fd, "DREQ_ACT "); end
ADDR_IREQ : begin $fwrite(fd, "IREQ "); end
ADDR_IREQ_SET : begin $fwrite(fd, "IREQ_SET "); if (wcyc_r) ireq_reg <= ahb_hwdata[3:0]; end
ADDR_IREQ_CLR : begin $fwrite(fd, "IREQ_CLR "); if (wcyc_r) ireq_reg <= ireq_reg | ahb_hwdata[3:0]; end
ADDR_IREQ_ACT : begin $fwrite(fd, "IREQ_ACT "); if (wcyc_r) ireq_reg <= ireq_reg &~ahb_hwdata[3:0]; end
default:
if (addr16_r[15:14] == 2'b01) $fwrite(fd, "KEYBUF128 ");
else if (addr16_r[15:14] == 2'b10) $fwrite(fd, "IPBUF128 ");
else if (addr16_r[15:14] == 2'b11) $fwrite(fd, "OPBUF128 ");
endcase
$fwrite(fd, " A+0x%04x, %s, D=0x", addr16_r, (wcyc_r) ? "W" : "R");
if (byte4_r[3]) $fwrite(fd, "%02x", ahb_hdata[31:24]); else $fwrite(fd, "--");
if (byte4_r[2]) $fwrite(fd, "%02x", ahb_hdata[23:16]); else $fwrite(fd, "--");
if (byte4_r[1]) $fwrite(fd, "%02x", ahb_hdata[15: 8]); else $fwrite(fd, "--");
if (byte4_r[0]) $fwrite(fd, "%02x", ahb_hdata[ 7: 0]); else $fwrite(fd, "--");
if (TIMESTAMP) $fwrite(fd, ", CYC=%8d (@%t)\n", cyc_count, $time); else $fwrite(fd, "\n");
end
if (any_change) begin
$fwrite(fd, "AESRQ: ");
if (drq_change) begin
$fwrite(fd, " drq_ipdma128=%b,",drq_ipdma128);
$fwrite(fd, " dlast_ipdma128=%b,",dlast_ipdma128);
$fwrite(fd, " drq_opdma128=%b,",drq_opdma128);
$fwrite(fd, " dlast_opdma128=%b",dlast_opdma128);
end
if (irq_change) begin
if (drq_change) $fwrite(fd, ",");
$fwrite(fd, " irq_merged=%b,",irq_merged);
$fwrite(fd, "irq_key128=%b,",irq_key128);
$fwrite(fd, "irq_ip128=%b,",irq_ip128);
$fwrite(fd, "irq_op128=%b,",irq_op128);
$fwrite(fd, "irq_error=%b",irq_error);
end
if (TIMESTAMP) $fwrite(fd, ", CYC=%8d (@%t)\n",cyc_count, $time); else $fwrite(fd, "\n");
end
end
$fclose(fd);
end
end
endmodule