mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: add crypto accelerator support and related tests
- Modified DMA error testbench to include crypto input and output AXI4 stream interfaces. - Updated DMA register testbench to integrate crypto AXI4 stream interfaces. - Enhanced SOC IRQ topology test to account for new crypto IRQs. - Added WS2812 DMA testbench modifications for crypto interfaces. - Introduced new Python tests for crypto primitives (AES, SHA, RSA) and APB register paths. - Implemented register parity tests to ensure synchronization between RTL and SDK constants. - Expanded DMA tests to validate crypto streaming endpoints. - Updated memory map tests to include crypto address definitions. - Adjusted SOC topology tests to reflect changes in IRQ mappings and peripheral counts.
This commit is contained in:
55 files changed
+6204
-189
No files matched your search
@@ -16,7 +16,7 @@ module apb4_topology_tb;
|
||||
begin
|
||||
s_decode_addr = address;
|
||||
#1;
|
||||
if (s_psel_comb !== (19'd1 << slot)) begin
|
||||
if (s_psel_comb !== (20'd1 << slot)) begin
|
||||
$fatal(1, "unexpected APB4 target slot for %h: got %b", address, s_psel_comb);
|
||||
end
|
||||
end
|
||||
@@ -42,6 +42,7 @@ module apb4_topology_tb;
|
||||
expect_select(`SOC_ADDR_APB4_I2C1_BASE, 17);
|
||||
expect_select(`SOC_ADDR_APB4_SDIO0_BASE, 15);
|
||||
expect_select(`SOC_ADDR_APB4_SDIO1_BASE, 18);
|
||||
expect_select(`SOC_ADDR_APB4_CRYPTO_BASE, 19);
|
||||
expect_disabled(`SOC_ADDR_APB4_GA_BASE);
|
||||
expect_disabled(`SOC_ADDR_APB4_APU_BASE);
|
||||
$display("SoC topology APB4 routing test passed");
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module crypto_apb_tb;
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic dma_input_proc;
|
||||
logic dma_output_proc;
|
||||
logic irq_o;
|
||||
|
||||
apb4_if apb4 (
|
||||
.pclk (clk_i),
|
||||
.presetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_in_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_out_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
apb4_crypto u_apb4_crypto (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.dma_input_proc_o (dma_input_proc),
|
||||
.dma_output_proc_o(dma_output_proc),
|
||||
.irq_o (irq_o),
|
||||
.apb4 (apb4),
|
||||
.crypto_in_axis (crypto_in_axis),
|
||||
.crypto_out_axis (crypto_out_axis)
|
||||
);
|
||||
|
||||
task automatic apb_write(input logic [11:0] offset, input logic [31:0] data,
|
||||
input logic [3:0] strobe, input logic expected_error);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
apb4.paddr = {20'd0, offset};
|
||||
apb4.pwdata = data;
|
||||
apb4.pstrb = strobe;
|
||||
apb4.pwrite = 1'b1;
|
||||
apb4.psel = 1'b1;
|
||||
apb4.penable = 1'b0;
|
||||
@(negedge clk_i);
|
||||
apb4.penable = 1'b1;
|
||||
#1;
|
||||
if (!apb4.pready || (apb4.pslverr != expected_error)) begin
|
||||
$fatal(1, "APB write %h ready/error mismatch", offset);
|
||||
end
|
||||
@(negedge clk_i);
|
||||
apb4.psel = 1'b0;
|
||||
apb4.penable = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic apb_read(input logic [11:0] offset, output logic [31:0] data,
|
||||
input logic expected_error);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
apb4.paddr = {20'd0, offset};
|
||||
apb4.pwdata = '0;
|
||||
apb4.pstrb = '0;
|
||||
apb4.pwrite = 1'b0;
|
||||
apb4.psel = 1'b1;
|
||||
apb4.penable = 1'b0;
|
||||
@(negedge clk_i);
|
||||
apb4.penable = 1'b1;
|
||||
#1;
|
||||
if (!apb4.pready || (apb4.pslverr != expected_error)) begin
|
||||
$fatal(1, "APB read %h ready/error mismatch", offset);
|
||||
end
|
||||
data = apb4.prdata;
|
||||
@(negedge clk_i);
|
||||
apb4.psel = 1'b0;
|
||||
apb4.penable = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic wait_mask(input logic [11:0] offset, input logic [31:0] mask,
|
||||
input logic [31:0] expected);
|
||||
logic [31:0] value;
|
||||
begin
|
||||
value = '0;
|
||||
while ((value & mask) != expected) begin
|
||||
apb_read(offset, value, 1'b0);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
logic [31:0] value;
|
||||
|
||||
apb4.paddr = '0;
|
||||
apb4.pprot = '0;
|
||||
apb4.psel = 1'b0;
|
||||
apb4.penable = 1'b0;
|
||||
apb4.pwrite = 1'b0;
|
||||
apb4.pwdata = '0;
|
||||
apb4.pstrb = '0;
|
||||
crypto_in_axis.tdata = '0;
|
||||
crypto_in_axis.tkeep = '0;
|
||||
crypto_in_axis.tstrb = '0;
|
||||
crypto_in_axis.tlast = 1'b0;
|
||||
crypto_in_axis.tid = '0;
|
||||
crypto_in_axis.tdest = '0;
|
||||
crypto_in_axis.tuser = '0;
|
||||
crypto_in_axis.tvalid = 1'b0;
|
||||
crypto_out_axis.tready = 1'b0;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
apb_read(12'h000, value, 1'b0);
|
||||
if (value != 32'h4352_5950) begin
|
||||
$fatal(1, "crypto IP ID mismatch");
|
||||
end
|
||||
apb_write(12'h01C, 32'h0000_001f, 4'hf, 1'b0);
|
||||
apb_write(12'h140, 32'h0302_0100, 4'hf, 1'b0);
|
||||
apb_write(12'h144, 32'h0706_0504, 4'hf, 1'b0);
|
||||
apb_write(12'h148, 32'h0b0a_0908, 4'hf, 1'b0);
|
||||
apb_write(12'h14c, 32'h0f0e_0d0c, 4'hf, 1'b0);
|
||||
apb_read(12'h140, value, 1'b1);
|
||||
apb_write(12'h104, 32'h0000_0000, 4'hf, 1'b0);
|
||||
apb_write(12'h128, 32'h0000_0001, 4'h1, 1'b0);
|
||||
wait_mask(12'h12c, 32'h1, 32'h1);
|
||||
apb_write(12'h10c, 32'd16, 4'hf, 1'b0);
|
||||
apb_write(12'h100, 32'h1, 4'h1, 1'b0);
|
||||
apb_write(12'h110, 32'h3322_1100, 4'hf, 1'b0);
|
||||
apb_write(12'h110, 32'h7766_5544, 4'hf, 1'b0);
|
||||
apb_write(12'h110, 32'hbbaa_9988, 4'hf, 1'b0);
|
||||
apb_write(12'h110, 32'hffee_ddcc, 4'hf, 1'b0);
|
||||
wait_mask(12'h118, 32'h2, 32'h2);
|
||||
apb_read(12'h114, value, 1'b0);
|
||||
if (value != 32'hd8e0_c469) $fatal(1, "AES output word 0 mismatch");
|
||||
apb_read(12'h114, value, 1'b0);
|
||||
if (value != 32'h3004_7b6a) $fatal(1, "AES output word 1 mismatch");
|
||||
apb_read(12'h114, value, 1'b0);
|
||||
if (value != 32'h80b7_cdd8) $fatal(1, "AES output word 2 mismatch");
|
||||
apb_read(12'h114, value, 1'b0);
|
||||
if (value != 32'h5ac5_b470) $fatal(1, "AES output word 3 mismatch");
|
||||
wait_mask(12'h018, 32'h1, 32'h1);
|
||||
if (!irq_o) $fatal(1, "AES completion did not assert IRQ");
|
||||
apb_write(12'h018, 32'h1, 4'h1, 1'b0);
|
||||
|
||||
apb_write(12'h204, 32'h1, 4'hf, 1'b0);
|
||||
apb_write(12'h20c, 32'd3, 4'hf, 1'b0);
|
||||
apb_write(12'h210, 32'd0, 4'hf, 1'b0);
|
||||
apb_write(12'h200, 32'h1, 4'h1, 1'b0);
|
||||
apb_write(12'h214, 32'h0063_6261, 4'h7, 1'b0);
|
||||
wait_mask(12'h218, 32'h2, 32'h2);
|
||||
apb_read(12'h240, value, 1'b0);
|
||||
if (value != 32'hba78_16bf) $fatal(1, "SHA digest word 0 mismatch");
|
||||
apb_read(12'h25c, value, 1'b0);
|
||||
if (value != 32'hf200_15ad) $fatal(1, "SHA digest word 7 mismatch");
|
||||
wait_mask(12'h018, 32'h2, 32'h2);
|
||||
|
||||
apb_write(12'h010, 32'h1, 4'h1, 1'b0);
|
||||
apb_read(12'h12c, value, 1'b0);
|
||||
if (value != 32'd0) $fatal(1, "zeroize did not invalidate AES key");
|
||||
wait_mask(12'h018, 32'h10, 32'h10);
|
||||
|
||||
$display("Crypto APB register tests passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,275 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module crypto_engine_tb;
|
||||
import crypto_pkg::*;
|
||||
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic zeroize_i = 1'b0;
|
||||
|
||||
logic aes_abort;
|
||||
logic aes_key_commit;
|
||||
logic [ 1:0] aes_key_size;
|
||||
logic [255:0] aes_key;
|
||||
logic aes_key_valid;
|
||||
logic aes_key_busy;
|
||||
logic aes_start;
|
||||
logic [ 1:0] aes_mode;
|
||||
logic aes_decrypt;
|
||||
logic [ 31:0] aes_length;
|
||||
logic [127:0] aes_iv;
|
||||
logic aes_input_valid;
|
||||
logic aes_input_ready;
|
||||
logic [ 31:0] aes_input_data;
|
||||
logic [ 3:0] aes_input_keep;
|
||||
logic aes_input_last;
|
||||
logic aes_output_valid;
|
||||
logic aes_output_ready;
|
||||
logic [ 31:0] aes_output_data;
|
||||
logic [ 3:0] aes_output_keep;
|
||||
logic aes_output_last;
|
||||
logic aes_busy;
|
||||
logic aes_done;
|
||||
logic aes_error;
|
||||
logic [ 31:0] aes_bytes_in;
|
||||
logic [ 31:0] aes_bytes_out;
|
||||
logic [ 31:0] aes_cycles;
|
||||
logic [127:0] aes_chain;
|
||||
|
||||
logic sha_abort;
|
||||
logic sha_start;
|
||||
logic sha256;
|
||||
logic [ 63:0] sha_length;
|
||||
logic sha_input_valid;
|
||||
logic sha_input_ready;
|
||||
logic [ 31:0] sha_input_data;
|
||||
logic [ 3:0] sha_input_keep;
|
||||
logic sha_input_last;
|
||||
logic sha_busy;
|
||||
logic sha_done;
|
||||
logic sha_error;
|
||||
logic sha_digest_valid;
|
||||
logic [255:0] sha_digest;
|
||||
logic [ 63:0] sha_bytes_in;
|
||||
logic [ 31:0] sha_cycles;
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
crypto_aes_engine u_crypto_aes_engine (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i (zeroize_i),
|
||||
.abort_i (aes_abort),
|
||||
.key_commit_i (aes_key_commit),
|
||||
.key_size_i (aes_key_size),
|
||||
.key_i (aes_key),
|
||||
.key_valid_o (aes_key_valid),
|
||||
.key_busy_o (aes_key_busy),
|
||||
.start_i (aes_start),
|
||||
.mode_i (aes_mode),
|
||||
.decrypt_i (aes_decrypt),
|
||||
.length_i (aes_length),
|
||||
.iv_i (aes_iv),
|
||||
.input_valid_i (aes_input_valid),
|
||||
.input_ready_o (aes_input_ready),
|
||||
.input_data_i (aes_input_data),
|
||||
.input_keep_i (aes_input_keep),
|
||||
.input_last_i (aes_input_last),
|
||||
.output_valid_o(aes_output_valid),
|
||||
.output_ready_i(aes_output_ready),
|
||||
.output_data_o (aes_output_data),
|
||||
.output_keep_o (aes_output_keep),
|
||||
.output_last_o (aes_output_last),
|
||||
.busy_o (aes_busy),
|
||||
.done_o (aes_done),
|
||||
.error_o (aes_error),
|
||||
.bytes_in_o (aes_bytes_in),
|
||||
.bytes_out_o (aes_bytes_out),
|
||||
.cycles_o (aes_cycles),
|
||||
.chain_o (aes_chain)
|
||||
);
|
||||
|
||||
crypto_sha2_engine u_crypto_sha2_engine (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i (zeroize_i),
|
||||
.abort_i (sha_abort),
|
||||
.start_i (sha_start),
|
||||
.sha256_i (sha256),
|
||||
.length_i (sha_length),
|
||||
.input_valid_i (sha_input_valid),
|
||||
.input_ready_o (sha_input_ready),
|
||||
.input_data_i (sha_input_data),
|
||||
.input_keep_i (sha_input_keep),
|
||||
.input_last_i (sha_input_last),
|
||||
.busy_o (sha_busy),
|
||||
.done_o (sha_done),
|
||||
.error_o (sha_error),
|
||||
.digest_valid_o(sha_digest_valid),
|
||||
.digest_o (sha_digest),
|
||||
.bytes_in_o (sha_bytes_in),
|
||||
.cycles_o (sha_cycles)
|
||||
);
|
||||
|
||||
task automatic aes_load_key(input logic [255:0] key);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
aes_key_size = AES_KEY_128;
|
||||
aes_key = key;
|
||||
aes_key_commit = 1'b1;
|
||||
@(negedge clk_i);
|
||||
aes_key_commit = 1'b0;
|
||||
wait (aes_key_valid);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic aes_begin(input logic [1:0] mode, input logic [31:0] length,
|
||||
input logic [127:0] iv);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
aes_mode = mode;
|
||||
aes_length = length;
|
||||
aes_iv = iv;
|
||||
aes_decrypt = 1'b0;
|
||||
aes_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
aes_start = 1'b0;
|
||||
wait (aes_busy);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic aes_send(input logic [31:0] data, input logic [3:0] keep, input logic last);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
aes_input_data = data;
|
||||
aes_input_keep = keep;
|
||||
aes_input_last = last;
|
||||
aes_input_valid = 1'b1;
|
||||
while (!aes_input_ready) begin
|
||||
@(negedge clk_i);
|
||||
end
|
||||
@(negedge clk_i);
|
||||
aes_input_valid = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic aes_expect(input logic [31:0] data, input logic [3:0] keep, input logic last);
|
||||
begin
|
||||
aes_output_ready = 1'b1;
|
||||
while (!aes_output_valid) begin
|
||||
@(negedge clk_i);
|
||||
end
|
||||
if ((aes_output_data != data) || (aes_output_keep != keep) || (aes_output_last != last)) begin
|
||||
$fatal(1, "AES stream mismatch: got %h/%h/%b expected %h/%h/%b", aes_output_data,
|
||||
aes_output_keep, aes_output_last, data, keep, last);
|
||||
end
|
||||
@(negedge clk_i);
|
||||
aes_output_ready = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic sha_begin(input logic use_sha256, input logic [63:0] length);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
sha256 = use_sha256;
|
||||
sha_length = length;
|
||||
sha_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
sha_start = 1'b0;
|
||||
wait (sha_busy);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic sha_send(input logic [31:0] data, input logic [3:0] keep, input logic last);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
sha_input_data = data;
|
||||
sha_input_keep = keep;
|
||||
sha_input_last = last;
|
||||
sha_input_valid = 1'b1;
|
||||
while (!sha_input_ready) begin
|
||||
@(negedge clk_i);
|
||||
end
|
||||
@(negedge clk_i);
|
||||
sha_input_valid = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
aes_abort = 1'b0;
|
||||
aes_key_commit = 1'b0;
|
||||
aes_key_size = AES_KEY_128;
|
||||
aes_key = '0;
|
||||
aes_start = 1'b0;
|
||||
aes_mode = AES_MODE_ECB;
|
||||
aes_decrypt = 1'b0;
|
||||
aes_length = '0;
|
||||
aes_iv = '0;
|
||||
aes_input_valid = 1'b0;
|
||||
aes_input_data = '0;
|
||||
aes_input_keep = '0;
|
||||
aes_input_last = 1'b0;
|
||||
aes_output_ready = 1'b0;
|
||||
sha_abort = 1'b0;
|
||||
sha_start = 1'b0;
|
||||
sha256 = 1'b1;
|
||||
sha_length = '0;
|
||||
sha_input_valid = 1'b0;
|
||||
sha_input_data = '0;
|
||||
sha_input_keep = '0;
|
||||
sha_input_last = 1'b0;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
aes_load_key(256'h000102030405060708090a0b0c0d0e0f_00000000000000000000000000000000);
|
||||
aes_begin(AES_MODE_ECB, 32'd16, '0);
|
||||
aes_send(32'h33221100, 4'hf, 1'b0);
|
||||
aes_send(32'h77665544, 4'hf, 1'b0);
|
||||
aes_send(32'hbbaa9988, 4'hf, 1'b0);
|
||||
aes_send(32'hffeeddcc, 4'hf, 1'b1);
|
||||
aes_expect(32'hd8e0c469, 4'hf, 1'b0);
|
||||
aes_expect(32'h30047b6a, 4'hf, 1'b0);
|
||||
aes_expect(32'h80b7cdd8, 4'hf, 1'b0);
|
||||
aes_expect(32'h5ac5b470, 4'hf, 1'b1);
|
||||
wait (aes_done);
|
||||
if (aes_error || (aes_bytes_in != 32'd16) || (aes_bytes_out != 32'd16)) begin
|
||||
$fatal(1, "AES ECB status mismatch");
|
||||
end
|
||||
|
||||
aes_load_key(256'h2b7e151628aed2a6abf7158809cf4f3c_00000000000000000000000000000000);
|
||||
aes_begin(AES_MODE_CTR, 32'd20, 128'hf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff);
|
||||
aes_send(32'he2bec16b, 4'hf, 1'b0);
|
||||
aes_send(32'h969f402e, 4'hf, 1'b0);
|
||||
aes_send(32'h117e3de9, 4'hf, 1'b0);
|
||||
aes_send(32'h2a179373, 4'hf, 1'b0);
|
||||
aes_send(32'h578a2dae, 4'hf, 1'b1);
|
||||
aes_expect(32'h91614d87, 4'hf, 1'b0);
|
||||
aes_expect(32'h26e320b6, 4'hf, 1'b0);
|
||||
aes_expect(32'h6468ef1b, 4'hf, 1'b0);
|
||||
aes_expect(32'hceb60d99, 4'hf, 1'b0);
|
||||
aes_expect(32'h6bf60698, 4'hf, 1'b1);
|
||||
wait (aes_done);
|
||||
if (aes_error || (aes_chain != 128'hf0f1f2f3f4f5f6f7f8f9fafbfcfdff01)) begin
|
||||
$fatal(1, "AES CTR status mismatch: error=%b chain=%h", aes_error, aes_chain);
|
||||
end
|
||||
|
||||
sha_begin(1'b1, 64'd3);
|
||||
sha_send(32'h00636261, 4'h7, 1'b1);
|
||||
wait (sha_done);
|
||||
if (sha_error || !sha_digest_valid ||
|
||||
(sha_digest != 256'hba7816bf8f01cfea414140de5dae2223b00361a396177a9c_b410ff61f20015ad)) begin
|
||||
$fatal(1, "SHA-256 stream result mismatch: %h", sha_digest);
|
||||
end
|
||||
|
||||
sha_begin(1'b0, 64'd0);
|
||||
wait (sha_done);
|
||||
if (sha_error || !sha_digest_valid ||
|
||||
(sha_digest != 256'hd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f_00000000)) begin
|
||||
$fatal(1, "SHA-224 empty result mismatch: %h", sha_digest);
|
||||
end
|
||||
|
||||
$display("Crypto streaming engine tests passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,144 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module crypto_primitive_tb;
|
||||
import crypto_pkg::*;
|
||||
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic zeroize_i = 1'b0;
|
||||
|
||||
logic aes_key_commit;
|
||||
logic [ 1:0] aes_key_size;
|
||||
logic [255:0] aes_key;
|
||||
logic aes_key_valid;
|
||||
logic aes_start;
|
||||
logic aes_decrypt;
|
||||
logic [127:0] aes_block_in;
|
||||
logic aes_busy;
|
||||
logic aes_done;
|
||||
logic [127:0] aes_block_out;
|
||||
|
||||
logic sha_start;
|
||||
logic [255:0] sha_state_in;
|
||||
logic [511:0] sha_block_in;
|
||||
logic sha_busy;
|
||||
logic sha_done;
|
||||
logic [255:0] sha_state_out;
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
crypto_aes_core u_crypto_aes_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i (zeroize_i),
|
||||
.key_commit_i(aes_key_commit),
|
||||
.key_size_i (aes_key_size),
|
||||
.key_i (aes_key),
|
||||
.key_valid_o (aes_key_valid),
|
||||
.start_i (aes_start),
|
||||
.decrypt_i (aes_decrypt),
|
||||
.block_i (aes_block_in),
|
||||
.busy_o (aes_busy),
|
||||
.done_o (aes_done),
|
||||
.block_o (aes_block_out)
|
||||
);
|
||||
|
||||
crypto_sha2_core u_crypto_sha2_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i(zeroize_i),
|
||||
.start_i (sha_start),
|
||||
.state_i (sha_state_in),
|
||||
.block_i (sha_block_in),
|
||||
.busy_o (sha_busy),
|
||||
.done_o (sha_done),
|
||||
.state_o (sha_state_out)
|
||||
);
|
||||
|
||||
task automatic aes_load_key(input logic [1:0] size, input logic [255:0] key);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
aes_key_size = size;
|
||||
aes_key = key;
|
||||
aes_key_commit = 1'b1;
|
||||
@(negedge clk_i);
|
||||
aes_key_commit = 1'b0;
|
||||
wait (aes_key_valid);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic aes_crypt(input logic decrypt, input logic [127:0] block,
|
||||
input logic [127:0] expected);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
aes_decrypt = decrypt;
|
||||
aes_block_in = block;
|
||||
aes_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
aes_start = 1'b0;
|
||||
wait (aes_done);
|
||||
if (aes_block_out != expected) begin
|
||||
$fatal(1, "AES result mismatch: got %h expected %h", aes_block_out, expected);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
aes_key_commit = 1'b0;
|
||||
aes_key_size = AES_KEY_128;
|
||||
aes_key = '0;
|
||||
aes_start = 1'b0;
|
||||
aes_decrypt = 1'b0;
|
||||
aes_block_in = '0;
|
||||
sha_start = 1'b0;
|
||||
sha_state_in = '0;
|
||||
sha_block_in = '0;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
aes_load_key(AES_KEY_128,
|
||||
256'h000102030405060708090a0b0c0d0e0f_00000000000000000000000000000000);
|
||||
aes_crypt(1'b0, 128'h00112233445566778899aabbccddeeff, 128'h69c4e0d86a7b0430d8cdb78070b4c55a);
|
||||
aes_crypt(1'b1, 128'h69c4e0d86a7b0430d8cdb78070b4c55a, 128'h00112233445566778899aabbccddeeff);
|
||||
|
||||
aes_load_key(AES_KEY_192,
|
||||
256'h000102030405060708090a0b0c0d0e0f1011121314151617_0000000000000000);
|
||||
aes_crypt(1'b0, 128'h00112233445566778899aabbccddeeff, 128'hdda97ca4864cdfe06eaf70a0ec0d7191);
|
||||
|
||||
aes_load_key(AES_KEY_256,
|
||||
256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f);
|
||||
aes_crypt(1'b0, 128'h00112233445566778899aabbccddeeff, 128'h8ea2b7ca516745bfeafc49904b496089);
|
||||
|
||||
@(negedge clk_i);
|
||||
sha_state_in = 256'h6a09e667bb67ae853c6ef372a54ff53a510e527f9b05688c1f83d9ab5be0cd19;
|
||||
sha_block_in = {
|
||||
32'h61626380,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000000,
|
||||
32'h00000018
|
||||
};
|
||||
sha_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
sha_start = 1'b0;
|
||||
wait (sha_done);
|
||||
if (sha_state_out != 256'hba7816bf8f01cfea414140de5dae2223b00361a396177a9c_b410ff61f20015ad) begin
|
||||
$fatal(1, "SHA-256 result mismatch: %h", sha_state_out);
|
||||
end
|
||||
|
||||
$display("Crypto AES and SHA primitive tests passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,163 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module crypto_rsa_tb;
|
||||
localparam int Bits = 64;
|
||||
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic zeroize_i = 1'b0;
|
||||
logic abort_i = 1'b0;
|
||||
logic prepare_i = 1'b0;
|
||||
logic start_i = 1'b0;
|
||||
logic private_i = 1'b0;
|
||||
logic [ 11:0] exponent_bits_i = '0;
|
||||
logic [Bits-1:0] modulus_i = '0;
|
||||
logic [Bits-1:0] exponent_i = '0;
|
||||
logic [Bits-1:0] base_i = '0;
|
||||
logic busy_o;
|
||||
logic done_o;
|
||||
logic error_o;
|
||||
logic prepared_o;
|
||||
logic result_valid_o;
|
||||
logic [Bits-1:0] result_o;
|
||||
logic [ 31:0] cycles_o;
|
||||
logic [ 31:0] progress_o;
|
||||
logic mont_start = 1'b0;
|
||||
logic [Bits-1:0] mont_left = '0;
|
||||
logic [Bits-1:0] mont_right = '0;
|
||||
logic mont_busy;
|
||||
logic mont_done;
|
||||
logic [Bits-1:0] mont_result;
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
crypto_rsa_core #(
|
||||
.Bits(Bits)
|
||||
) u_crypto_rsa_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i (zeroize_i),
|
||||
.abort_i (abort_i),
|
||||
.prepare_i (prepare_i),
|
||||
.start_i (start_i),
|
||||
.private_i (private_i),
|
||||
.exponent_bits_i(exponent_bits_i),
|
||||
.modulus_i (modulus_i),
|
||||
.exponent_i (exponent_i),
|
||||
.base_i (base_i),
|
||||
.busy_o (busy_o),
|
||||
.done_o (done_o),
|
||||
.error_o (error_o),
|
||||
.prepared_o (prepared_o),
|
||||
.result_valid_o (result_valid_o),
|
||||
.result_o (result_o),
|
||||
.cycles_o (cycles_o),
|
||||
.progress_o (progress_o)
|
||||
);
|
||||
|
||||
crypto_montgomery #(
|
||||
.Bits(Bits)
|
||||
) u_direct_montgomery (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.zeroize_i (zeroize_i),
|
||||
.start_i (mont_start),
|
||||
.left_i (mont_left),
|
||||
.right_i (mont_right),
|
||||
.modulus_i (modulus_i),
|
||||
.n0_prime_i(32'h03030303),
|
||||
.busy_o (mont_busy),
|
||||
.done_o (mont_done),
|
||||
.result_o (mont_result)
|
||||
);
|
||||
|
||||
task automatic pulse_prepare;
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
prepare_i = 1'b1;
|
||||
@(negedge clk_i);
|
||||
prepare_i = 1'b0;
|
||||
wait (done_o);
|
||||
if (!prepared_o || error_o) begin
|
||||
$fatal(1, "RSA modulus preparation failed");
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic pulse_start(input logic is_private);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
private_i = is_private;
|
||||
start_i = 1'b1;
|
||||
@(negedge clk_i);
|
||||
start_i = 1'b0;
|
||||
wait (done_o);
|
||||
if (!result_valid_o || error_o) begin
|
||||
$fatal(1, "RSA modular exponentiation failed");
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
modulus_i = 64'hffffffea00000055;
|
||||
pulse_prepare();
|
||||
if (u_crypto_rsa_core.s_r2_q != 64'h00001afbffff7b85) begin
|
||||
$fatal(1, "RSA R2 mismatch: %h", u_crypto_rsa_core.s_r2_q);
|
||||
end
|
||||
if (u_crypto_rsa_core.s_n0_prime_q != 32'h03030303) begin
|
||||
$fatal(1, "RSA n0 prime mismatch: %h", u_crypto_rsa_core.s_n0_prime_q);
|
||||
end
|
||||
|
||||
@(negedge clk_i);
|
||||
mont_left = 64'h0123456789abcdef;
|
||||
mont_right = 64'h00001afbffff7b85;
|
||||
mont_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
mont_start = 1'b0;
|
||||
wait (mont_done);
|
||||
if (mont_result != 64'h9abcdefafa4fa4f2) begin
|
||||
$fatal(1, "direct Montgomery result mismatch: %h", mont_result);
|
||||
end
|
||||
|
||||
@(negedge clk_i);
|
||||
mont_left = 64'h9abcdefafa4fa4f2;
|
||||
mont_right = 64'h9abcdefafa4fa4f2;
|
||||
mont_start = 1'b1;
|
||||
@(negedge clk_i);
|
||||
mont_start = 1'b0;
|
||||
wait (mont_done);
|
||||
if (mont_result != 64'hba9c5877ea4e6ea3) begin
|
||||
$fatal(1, "direct Montgomery square mismatch: %h", mont_result);
|
||||
end
|
||||
|
||||
base_i = 64'h0123456789abcdef;
|
||||
exponent_i = 64'h0000000000010001;
|
||||
exponent_bits_i = 12'd17;
|
||||
pulse_start(1'b0);
|
||||
if (result_o != 64'h61c4c4e9f38bdddb) begin
|
||||
$fatal(1, "RSA public result mismatch: %h", result_o);
|
||||
end
|
||||
|
||||
base_i = 64'h61c4c4e9f38bdddb;
|
||||
exponent_i = 64'h81817e725d5da2d9;
|
||||
exponent_bits_i = 12'd64;
|
||||
pulse_start(1'b1);
|
||||
if (result_o != 64'h0123456789abcdef) begin
|
||||
$fatal(1, "RSA private result mismatch: %h", result_o);
|
||||
end
|
||||
|
||||
@(negedge clk_i);
|
||||
zeroize_i = 1'b1;
|
||||
@(negedge clk_i);
|
||||
zeroize_i = 1'b0;
|
||||
if (prepared_o || result_valid_o) begin
|
||||
$fatal(1, "RSA zeroize retained prepared or result state");
|
||||
end
|
||||
|
||||
$display("Crypto RSA Montgomery tests passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,264 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module dma_crypto_tb;
|
||||
import dma_pkg::*;
|
||||
|
||||
localparam int NumChannels = 6;
|
||||
localparam logic [31:0] SourceBase = 32'h4000_0000;
|
||||
localparam logic [31:0] DestinationBase = 32'h4000_1000;
|
||||
localparam logic [31:0] TransferBytes = 32'd64;
|
||||
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic [NumChannels*32-1:0] ch_cfg_i = '0;
|
||||
logic [NumChannels*32-1:0] src_addr_i = '0;
|
||||
logic [NumChannels*32-1:0] dst_addr_i = '0;
|
||||
logic [NumChannels*32-1:0] byte_count_i = '0;
|
||||
logic [NumChannels*32-1:0] request_sel_i = '0;
|
||||
logic [NumChannels*32-1:0] burst_cfg_i = '0;
|
||||
logic [ NumChannels-1:0] start_i = '0;
|
||||
logic [ NumChannels-1:0] busy_o;
|
||||
logic [ NumChannels-1:0] done_o;
|
||||
logic [ NumChannels-1:0] error_o;
|
||||
logic [NumChannels*32-1:0] bytes_done_o;
|
||||
logic [ 31:0] cycle_q = '0;
|
||||
logic read_active_q = 1'b0;
|
||||
logic [ 31:0] read_addr_q = '0;
|
||||
logic [ 4:0] read_beats_q = '0;
|
||||
logic [ 4:0] read_index_q = '0;
|
||||
logic write_active_q = 1'b0;
|
||||
logic [ 31:0] write_addr_q = '0;
|
||||
logic [ 4:0] write_beats_q = '0;
|
||||
logic [ 4:0] write_index_q = '0;
|
||||
logic write_response_q = 1'b0;
|
||||
logic stream_last_seen_q = 1'b0;
|
||||
integer write_count = 0;
|
||||
|
||||
dma_req_if req ();
|
||||
axi4_if axi4 (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if i2s_tx_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if i2s_rx_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if dvp_rx_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_in_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_out_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
assign req.i2s_tx_proc = 1'b1;
|
||||
assign req.i2s_rx_proc = 1'b1;
|
||||
assign req.qspi_tx_proc = 1'b1;
|
||||
assign req.qspi_rx_proc = 1'b1;
|
||||
assign req.uart_tx_proc = 1'b1;
|
||||
assign req.uart_rx_proc = 1'b1;
|
||||
assign req.i2c0_tx_proc = 1'b1;
|
||||
assign req.i2c0_rx_proc = 1'b1;
|
||||
assign req.i2c1_tx_proc = 1'b1;
|
||||
assign req.i2c1_rx_proc = 1'b1;
|
||||
assign req.crypto_in_proc = 1'b1;
|
||||
assign req.crypto_out_proc = 1'b1;
|
||||
|
||||
assign axi4.arready = !read_active_q && cycle_q[0];
|
||||
assign axi4.rid = '0;
|
||||
assign axi4.rdata = 32'hcafe_0000 | ((read_addr_q - SourceBase) >> 2) | read_index_q;
|
||||
assign axi4.rresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.rlast = (read_index_q + 1'b1) == read_beats_q;
|
||||
assign axi4.ruser = '0;
|
||||
assign axi4.rvalid = read_active_q;
|
||||
assign axi4.awready = !write_active_q && !write_response_q && cycle_q[0];
|
||||
assign axi4.wready = write_active_q && cycle_q[1];
|
||||
assign axi4.bid = '0;
|
||||
assign axi4.bresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.buser = '0;
|
||||
assign axi4.bvalid = write_response_q;
|
||||
|
||||
assign i2s_tx_axis.tready = 1'b0;
|
||||
assign i2s_rx_axis.tdata = '0;
|
||||
assign i2s_rx_axis.tkeep = '0;
|
||||
assign i2s_rx_axis.tstrb = '0;
|
||||
assign i2s_rx_axis.tlast = 1'b0;
|
||||
assign i2s_rx_axis.tid = '0;
|
||||
assign i2s_rx_axis.tdest = '0;
|
||||
assign i2s_rx_axis.tuser = '0;
|
||||
assign i2s_rx_axis.tvalid = 1'b0;
|
||||
assign dvp_rx_axis.tdata = '0;
|
||||
assign dvp_rx_axis.tkeep = '0;
|
||||
assign dvp_rx_axis.tstrb = '0;
|
||||
assign dvp_rx_axis.tlast = 1'b0;
|
||||
assign dvp_rx_axis.tid = '0;
|
||||
assign dvp_rx_axis.tdest = '0;
|
||||
assign dvp_rx_axis.tuser = '0;
|
||||
assign dvp_rx_axis.tvalid = 1'b0;
|
||||
|
||||
assign crypto_in_axis.tready = crypto_out_axis.tready && cycle_q[0];
|
||||
assign crypto_out_axis.tdata = crypto_in_axis.tdata;
|
||||
assign crypto_out_axis.tkeep = crypto_in_axis.tkeep;
|
||||
assign crypto_out_axis.tstrb = crypto_in_axis.tstrb;
|
||||
assign crypto_out_axis.tlast = crypto_in_axis.tlast;
|
||||
assign crypto_out_axis.tid = crypto_in_axis.tid;
|
||||
assign crypto_out_axis.tdest = crypto_in_axis.tdest;
|
||||
assign crypto_out_axis.tuser = crypto_in_axis.tuser;
|
||||
assign crypto_out_axis.tvalid = crypto_in_axis.tvalid && cycle_q[0];
|
||||
|
||||
dma_core #(
|
||||
.NumChannels (NumChannels),
|
||||
.MaxBurstBeats(16),
|
||||
.FifoDepth (16)
|
||||
) u_dma_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.global_reset_i (1'b0),
|
||||
.global_error_clear_i (1'b0),
|
||||
.ch_cfg_i (ch_cfg_i),
|
||||
.src_addr_i (src_addr_i),
|
||||
.dst_addr_i (dst_addr_i),
|
||||
.byte_count_i (byte_count_i),
|
||||
.request_sel_i (request_sel_i),
|
||||
.burst_cfg_i (burst_cfg_i),
|
||||
.start_i (start_i),
|
||||
.suspend_i ('0),
|
||||
.resume_i ('0),
|
||||
.abort_i ('0),
|
||||
.channel_reset_i ('0),
|
||||
.event_clear_i ('0),
|
||||
.busy_o (busy_o),
|
||||
.suspended_o (),
|
||||
.done_o (done_o),
|
||||
.aborted_o (),
|
||||
.error_o (error_o),
|
||||
.stream_last_o (),
|
||||
.event_status_o (),
|
||||
.error_status_o (),
|
||||
.error_addr_o (),
|
||||
.current_src_o (),
|
||||
.current_dst_o (),
|
||||
.remaining_o (),
|
||||
.bytes_done_o (bytes_done_o),
|
||||
.stall_cycles_lo_o (),
|
||||
.stall_cycles_hi_o (),
|
||||
.first_error_valid_o (),
|
||||
.first_error_channel_o(),
|
||||
.first_error_status_o (),
|
||||
.first_error_addr_hi_o(),
|
||||
.request_status_o (),
|
||||
.xpi_xfer_done_o (),
|
||||
.req (req),
|
||||
.axi4 (axi4),
|
||||
.i2s_tx_axis (i2s_tx_axis),
|
||||
.i2s_rx_axis (i2s_rx_axis),
|
||||
.dvp_rx_axis (dvp_rx_axis),
|
||||
.crypto_in_axis (crypto_in_axis),
|
||||
.crypto_out_axis (crypto_out_axis)
|
||||
);
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
cycle_q <= '0;
|
||||
read_active_q <= 1'b0;
|
||||
write_active_q <= 1'b0;
|
||||
write_response_q <= 1'b0;
|
||||
stream_last_seen_q <= 1'b0;
|
||||
write_count <= 0;
|
||||
end else begin
|
||||
cycle_q <= cycle_q + 1'b1;
|
||||
if (axi4.arvalid && axi4.arready) begin
|
||||
read_active_q <= 1'b1;
|
||||
read_addr_q <= axi4.araddr;
|
||||
read_beats_q <= axi4.arlen + 1'b1;
|
||||
read_index_q <= '0;
|
||||
end
|
||||
if (axi4.rvalid && axi4.rready) begin
|
||||
if (axi4.rlast) begin
|
||||
read_active_q <= 1'b0;
|
||||
end else begin
|
||||
read_index_q <= read_index_q + 1'b1;
|
||||
end
|
||||
end
|
||||
if (axi4.awvalid && axi4.awready) begin
|
||||
write_active_q <= 1'b1;
|
||||
write_addr_q <= axi4.awaddr;
|
||||
write_beats_q <= axi4.awlen + 1'b1;
|
||||
write_index_q <= '0;
|
||||
end
|
||||
if (axi4.wvalid && axi4.wready) begin
|
||||
if ((write_addr_q + (write_index_q << 2)) != (DestinationBase + (write_count * 4))) begin
|
||||
$fatal(1, "crypto DMA write address mismatch");
|
||||
end
|
||||
if (axi4.wdata != (32'hcafe_0000 | write_count)) begin
|
||||
$fatal(1, "crypto DMA write data mismatch: %h at %0d", axi4.wdata, write_count);
|
||||
end
|
||||
write_count <= write_count + 1;
|
||||
if (axi4.wlast) begin
|
||||
if ((write_index_q + 1'b1) != write_beats_q) begin
|
||||
$fatal(1, "crypto DMA WLAST mismatch");
|
||||
end
|
||||
write_active_q <= 1'b0;
|
||||
write_response_q <= 1'b1;
|
||||
end else begin
|
||||
write_index_q <= write_index_q + 1'b1;
|
||||
end
|
||||
end
|
||||
if (axi4.bvalid && axi4.bready) begin
|
||||
write_response_q <= 1'b0;
|
||||
end
|
||||
if (crypto_in_axis.tvalid && crypto_in_axis.tready && crypto_in_axis.tlast) begin
|
||||
stream_last_seen_q <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
integer wait_cycles;
|
||||
|
||||
ch_cfg_i[(4*32)+:32] = {22'd0, 2'd3, 1'b0, 1'b1, DMA_WIDTH_32, 1'b0, DMA_KIND_MM_TO_STREAM};
|
||||
src_addr_i[(4*32)+:32] = SourceBase;
|
||||
byte_count_i[(4*32)+:32] = TransferBytes;
|
||||
request_sel_i[(4*32)+:32] = {28'd0, DMA_REQUEST_CRYPTO_IN};
|
||||
burst_cfg_i[(4*32)+:32] = 32'd8;
|
||||
ch_cfg_i[(5*32)+:32] = {22'd0, 2'd3, 1'b1, 1'b0, DMA_WIDTH_32, 1'b0, DMA_KIND_STREAM_TO_MM};
|
||||
dst_addr_i[(5*32)+:32] = DestinationBase;
|
||||
byte_count_i[(5*32)+:32] = TransferBytes;
|
||||
request_sel_i[(5*32)+:32] = {28'd0, DMA_REQUEST_CRYPTO_OUT};
|
||||
burst_cfg_i[(5*32)+:32] = 32'd8;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
@(negedge clk_i);
|
||||
start_i[5:4] = 2'b11;
|
||||
@(negedge clk_i);
|
||||
start_i = '0;
|
||||
wait_cycles = 0;
|
||||
while (!(done_o[4] && done_o[5]) && (wait_cycles < 5000)) begin
|
||||
@(posedge clk_i);
|
||||
wait_cycles = wait_cycles + 1;
|
||||
end
|
||||
if (!(done_o[4] && done_o[5])) begin
|
||||
$fatal(1, "crypto DMA endpoint test timeout");
|
||||
end
|
||||
if ((error_o != '0) || (write_count != 16) || !stream_last_seen_q ||
|
||||
(bytes_done_o[(4*32)+:32] != TransferBytes) ||
|
||||
(bytes_done_o[(5*32)+:32] != TransferBytes)) begin
|
||||
$fatal(1, "crypto DMA result mismatch errors=%b writes=%0d last=%b", error_o, write_count,
|
||||
stream_last_seen_q);
|
||||
end
|
||||
$display("DMA crypto channel 4/5 streaming test passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
+35
-14
@@ -40,8 +40,8 @@ module dma_error_tb;
|
||||
logic [NumChannels*32-1:0] stall_cycles_hi_o;
|
||||
logic first_error_valid_o;
|
||||
logic [ 1:0] first_error_channel_o;
|
||||
logic [ 31:0] first_error_status_o;
|
||||
logic [ 31:0] first_error_addr_o;
|
||||
logic [ 8:0] first_error_status_o;
|
||||
logic [ 15:0] first_error_addr_hi_o;
|
||||
logic [ 15:0] request_status_o;
|
||||
logic xpi_xfer_done_o;
|
||||
logic error_mode = 1'b0;
|
||||
@@ -91,6 +91,14 @@ module dma_error_tb;
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_in_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_out_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
@@ -131,6 +139,15 @@ module dma_error_tb;
|
||||
assign dvp_rx_axis.tdest = '0;
|
||||
assign dvp_rx_axis.tuser = '0;
|
||||
assign dvp_rx_axis.tvalid = 1'b0;
|
||||
assign crypto_in_axis.tready = 1'b0;
|
||||
assign crypto_out_axis.tdata = '0;
|
||||
assign crypto_out_axis.tkeep = '0;
|
||||
assign crypto_out_axis.tstrb = '0;
|
||||
assign crypto_out_axis.tlast = 1'b0;
|
||||
assign crypto_out_axis.tid = '0;
|
||||
assign crypto_out_axis.tdest = '0;
|
||||
assign crypto_out_axis.tuser = '0;
|
||||
assign crypto_out_axis.tvalid = 1'b0;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
@@ -255,14 +272,16 @@ module dma_error_tb;
|
||||
.first_error_valid_o (first_error_valid_o),
|
||||
.first_error_channel_o(first_error_channel_o),
|
||||
.first_error_status_o (first_error_status_o),
|
||||
.first_error_addr_o (first_error_addr_o),
|
||||
.first_error_addr_hi_o(first_error_addr_hi_o),
|
||||
.request_status_o (request_status_o),
|
||||
.xpi_xfer_done_o (xpi_xfer_done_o),
|
||||
.req (req),
|
||||
.axi4 (axi4),
|
||||
.i2s_tx_axis (i2s_tx_axis),
|
||||
.i2s_rx_axis (i2s_rx_axis),
|
||||
.dvp_rx_axis (dvp_rx_axis)
|
||||
.dvp_rx_axis (dvp_rx_axis),
|
||||
.crypto_in_axis (crypto_in_axis),
|
||||
.crypto_out_axis (crypto_out_axis)
|
||||
);
|
||||
|
||||
task automatic configure_channel(input integer channel, input logic [2:0] kind,
|
||||
@@ -327,16 +346,18 @@ module dma_error_tb;
|
||||
logic [31:0] stalled_stream_data;
|
||||
logic stalled_stream_last;
|
||||
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
req.crypto_in_proc = 1'b1;
|
||||
req.crypto_out_proc = 1'b1;
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
|
||||
+69
-48
@@ -31,39 +31,56 @@ module dma_reg_tb;
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_in_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_out_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
assign axi4.arready = !read_active_q;
|
||||
assign axi4.rid = '0;
|
||||
assign axi4.rdata = 32'hC0DE_0001;
|
||||
assign axi4.rresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.rlast = 1'b1;
|
||||
assign axi4.ruser = '0;
|
||||
assign axi4.rvalid = read_active_q;
|
||||
assign axi4.awready = !write_active_q && !write_response_q;
|
||||
assign axi4.wready = write_active_q;
|
||||
assign axi4.bid = '0;
|
||||
assign axi4.bresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.buser = '0;
|
||||
assign axi4.bvalid = write_response_q && allow_write_response;
|
||||
assign i2s_tx_axis.tready = 1'b0;
|
||||
assign i2s_rx_axis.tdata = '0;
|
||||
assign i2s_rx_axis.tkeep = '0;
|
||||
assign i2s_rx_axis.tstrb = '0;
|
||||
assign i2s_rx_axis.tlast = 1'b0;
|
||||
assign i2s_rx_axis.tid = '0;
|
||||
assign i2s_rx_axis.tdest = '0;
|
||||
assign i2s_rx_axis.tuser = '0;
|
||||
assign i2s_rx_axis.tvalid = 1'b0;
|
||||
assign dvp_rx_axis.tdata = '0;
|
||||
assign dvp_rx_axis.tkeep = '0;
|
||||
assign dvp_rx_axis.tstrb = '0;
|
||||
assign dvp_rx_axis.tlast = 1'b0;
|
||||
assign dvp_rx_axis.tid = '0;
|
||||
assign dvp_rx_axis.tdest = '0;
|
||||
assign dvp_rx_axis.tuser = '0;
|
||||
assign dvp_rx_axis.tvalid = 1'b0;
|
||||
assign axi4.arready = !read_active_q;
|
||||
assign axi4.rid = '0;
|
||||
assign axi4.rdata = 32'hC0DE_0001;
|
||||
assign axi4.rresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.rlast = 1'b1;
|
||||
assign axi4.ruser = '0;
|
||||
assign axi4.rvalid = read_active_q;
|
||||
assign axi4.awready = !write_active_q && !write_response_q;
|
||||
assign axi4.wready = write_active_q;
|
||||
assign axi4.bid = '0;
|
||||
assign axi4.bresp = `AXI4_RESP_OKAY;
|
||||
assign axi4.buser = '0;
|
||||
assign axi4.bvalid = write_response_q && allow_write_response;
|
||||
assign i2s_tx_axis.tready = 1'b0;
|
||||
assign i2s_rx_axis.tdata = '0;
|
||||
assign i2s_rx_axis.tkeep = '0;
|
||||
assign i2s_rx_axis.tstrb = '0;
|
||||
assign i2s_rx_axis.tlast = 1'b0;
|
||||
assign i2s_rx_axis.tid = '0;
|
||||
assign i2s_rx_axis.tdest = '0;
|
||||
assign i2s_rx_axis.tuser = '0;
|
||||
assign i2s_rx_axis.tvalid = 1'b0;
|
||||
assign dvp_rx_axis.tdata = '0;
|
||||
assign dvp_rx_axis.tkeep = '0;
|
||||
assign dvp_rx_axis.tstrb = '0;
|
||||
assign dvp_rx_axis.tlast = 1'b0;
|
||||
assign dvp_rx_axis.tid = '0;
|
||||
assign dvp_rx_axis.tdest = '0;
|
||||
assign dvp_rx_axis.tuser = '0;
|
||||
assign dvp_rx_axis.tvalid = 1'b0;
|
||||
assign crypto_in_axis.tready = 1'b0;
|
||||
assign crypto_out_axis.tdata = '0;
|
||||
assign crypto_out_axis.tkeep = '0;
|
||||
assign crypto_out_axis.tstrb = '0;
|
||||
assign crypto_out_axis.tlast = 1'b0;
|
||||
assign crypto_out_axis.tid = '0;
|
||||
assign crypto_out_axis.tdest = '0;
|
||||
assign crypto_out_axis.tuser = '0;
|
||||
assign crypto_out_axis.tvalid = 1'b0;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
@@ -109,7 +126,9 @@ module dma_reg_tb;
|
||||
.axi4 (axi4),
|
||||
.i2s_tx_axis (i2s_tx_axis),
|
||||
.i2s_rx_axis (i2s_rx_axis),
|
||||
.dvp_rx_axis (dvp_rx_axis)
|
||||
.dvp_rx_axis (dvp_rx_axis),
|
||||
.crypto_in_axis (crypto_in_axis),
|
||||
.crypto_out_axis(crypto_out_axis)
|
||||
);
|
||||
|
||||
task automatic apb_write(input logic [31:0] address, input logic [31:0] data,
|
||||
@@ -161,23 +180,25 @@ module dma_reg_tb;
|
||||
initial begin
|
||||
logic [31:0] value;
|
||||
|
||||
apb4.paddr = '0;
|
||||
apb4.pprot = '0;
|
||||
apb4.psel = 1'b0;
|
||||
apb4.penable = 1'b0;
|
||||
apb4.pwrite = 1'b0;
|
||||
apb4.pwdata = '0;
|
||||
apb4.pstrb = '0;
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
apb4.paddr = '0;
|
||||
apb4.pprot = '0;
|
||||
apb4.psel = 1'b0;
|
||||
apb4.penable = 1'b0;
|
||||
apb4.pwrite = 1'b0;
|
||||
apb4.pwdata = '0;
|
||||
apb4.pstrb = '0;
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
req.crypto_in_proc = 1'b1;
|
||||
req.crypto_out_proc = 1'b1;
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ module soc_irq_topology_tb;
|
||||
14: expect_irq(32'd1 << 20);
|
||||
16: expect_irq(32'd1 << 10);
|
||||
17: expect_irq(32'd1 << 21);
|
||||
18: expect_irq(32'd1 << 23);
|
||||
default: expect_irq(32'd1 << (bit_index + 7));
|
||||
endcase
|
||||
end
|
||||
@@ -62,7 +63,7 @@ module soc_irq_topology_tb;
|
||||
$fatal(1, "SDIO core IRQ bits are not low when sources are low: IRQ10=%b IRQ21=%b",
|
||||
s_irq[10], s_irq[21]);
|
||||
end
|
||||
if ((s_irq[31:21] !== '0) || (s_irq[19:18] !== '0)) begin
|
||||
if ((s_irq[31:24] !== '0) || (s_irq[19:18] !== '0)) begin
|
||||
$fatal(1, "unallocated core IRQ bits are not low: %h", s_irq);
|
||||
end
|
||||
|
||||
|
||||
+39
-18
@@ -72,6 +72,14 @@ module ws2812_dma_tb;
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_in_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
axi4_stream_if crypto_out_axis (
|
||||
.aclk (clk_i),
|
||||
.aresetn(rst_n_i)
|
||||
);
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
@@ -119,6 +127,15 @@ module ws2812_dma_tb;
|
||||
assign dvp_rx_axis.tdest = '0;
|
||||
assign dvp_rx_axis.tuser = '0;
|
||||
assign dvp_rx_axis.tvalid = 1'b0;
|
||||
assign crypto_in_axis.tready = 1'b0;
|
||||
assign crypto_out_axis.tdata = '0;
|
||||
assign crypto_out_axis.tkeep = '0;
|
||||
assign crypto_out_axis.tstrb = '0;
|
||||
assign crypto_out_axis.tlast = 1'b0;
|
||||
assign crypto_out_axis.tid = '0;
|
||||
assign crypto_out_axis.tdest = '0;
|
||||
assign crypto_out_axis.tuser = '0;
|
||||
assign crypto_out_axis.tvalid = 1'b0;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
@@ -216,14 +233,16 @@ module ws2812_dma_tb;
|
||||
.first_error_valid_o (),
|
||||
.first_error_channel_o(),
|
||||
.first_error_status_o (),
|
||||
.first_error_addr_o (),
|
||||
.first_error_addr_hi_o(),
|
||||
.request_status_o (),
|
||||
.xpi_xfer_done_o (),
|
||||
.req (req),
|
||||
.axi4 (axi4),
|
||||
.i2s_tx_axis (i2s_tx_axis),
|
||||
.i2s_rx_axis (i2s_rx_axis),
|
||||
.dvp_rx_axis (dvp_rx_axis)
|
||||
.dvp_rx_axis (dvp_rx_axis),
|
||||
.crypto_in_axis (crypto_in_axis),
|
||||
.crypto_out_axis (crypto_out_axis)
|
||||
);
|
||||
|
||||
assign dma_done = dma_done_vector[0];
|
||||
@@ -290,22 +309,24 @@ module ws2812_dma_tb;
|
||||
end
|
||||
|
||||
initial begin
|
||||
pixels[0] = 24'h800001;
|
||||
pixels[1] = 24'h010203;
|
||||
pixels[2] = 24'hA5A5A5;
|
||||
pixels[3] = 24'h5A5A5A;
|
||||
pixels[4] = 24'hFFFFFF;
|
||||
pixels[5] = 24'h000000;
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
pixels[0] = 24'h800001;
|
||||
pixels[1] = 24'h010203;
|
||||
pixels[2] = 24'hA5A5A5;
|
||||
pixels[3] = 24'h5A5A5A;
|
||||
pixels[4] = 24'hFFFFFF;
|
||||
pixels[5] = 24'h000000;
|
||||
req.i2s_tx_proc = 1'b1;
|
||||
req.i2s_rx_proc = 1'b1;
|
||||
req.qspi_tx_proc = 1'b1;
|
||||
req.qspi_rx_proc = 1'b1;
|
||||
req.uart_tx_proc = 1'b1;
|
||||
req.uart_rx_proc = 1'b1;
|
||||
req.i2c0_tx_proc = 1'b1;
|
||||
req.i2c0_rx_proc = 1'b1;
|
||||
req.i2c1_tx_proc = 1'b1;
|
||||
req.i2c1_rx_proc = 1'b1;
|
||||
req.crypto_in_proc = 1'b1;
|
||||
req.crypto_out_proc = 1'b1;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
Reference in new issue
Block a user