Ich habe einen AES-256-Algorithmus realisiert, der einen 128-Bit-std_logic_vector (Klartext) mit einem 256-Bit-std_logic_vector (Master_key) verschlüsselt. Ich habe eine Testbank erstellt, um das Verhalten des Verschlüsselungsprozesses zu überprüfen, und jetzt möchte ich diesen Algorithmus auf meinem Basys3-Board implementieren (ich verwende Vivado als IDE). Meine Fragen sind:
Wie kann ich die Eingabevektoren abbilden? Sollte ich Signale in meiner Architektur deklarieren, obwohl ich weiß, dass ich nicht genügend I/O-Ports habe?
Eine serielle Schnittstelle verwendet die wenigsten Pins. Von allen seriellen Schnittstellen ist SPI am einfachsten zu implementieren. (Ich denke, es sind ungefähr fünf Zeilen Code). Da eine SPI-Schnittstelle Daten gleichzeitig ein- und ausgibt, können Sie sie auch zum Auslesen des Ergebnisses verwenden.
Ok, ich habe es gerade versucht und es waren etwas mehr als fünf Zeilen, die sich hauptsächlich mit der Synchronisation der SPI-Signale auf eine (interne höherfrequente) Systemuhr befassten.
Der folgende Code wurde schnell zusammen gehackt und scheint zu funktionieren:
//
// Simple dumb SPI interface:
// one big long shift register
// Relies on a system clock which is
// much faster then the SPI clock
//
// User MUST send the right amount of bits in one go.
//
module spi_dumb
#(parameter DW = 128) // Number of internal data bits
(
// Usual system signals
input clk, // system clock
input reset_n, // system reset
// SPI interface
input sclk,
input sel_n,
input mosi,
output miso,
// Internal data interface
input [DW-1:0] par_tx, // Data to transmit
output reg [DW-1:0] par_rx, // Data received
output reg valid // Data has arrived
);
reg sclk_meta,sclk_sync,sclk_prev;
reg seln_meta,seln_sync,seln_prev;
wire clock_edge;
// assign clock_edge = ~sclk_prev & sclk_sync; // Rising edge
assign clock_edge = sclk_prev & ~sclk_sync; // Falling edge
always @(posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
valid <= 1'b0;
sclk_meta <= 1'b0;
sclk_sync <= 1'b0;
sclk_prev <= 1'b0;
seln_meta <= 1'b0;
seln_sync <= 1'b0;
seln_prev <= 1'b0;
end
else
begin
// Sychronise the clkc and select
sclk_meta <= sclk;
sclk_sync <= sclk_meta;
sclk_prev <= sclk_sync;
seln_meta <= sel_n;
seln_sync <= seln_meta;
seln_prev <= seln_sync;
// On falling edge SPI-Select load the shift register
if (seln_prev & ~seln_sync)
begin
par_rx <= par_tx;
valid <= 1'b0;
end
// On rising edge SPI-Select mark the data as valid
if (~seln_prev & seln_sync)
valid <= 1'b1;
// If SPI select is low and we have a clock edge pick up the data
// We assume the mosi data is stable by then
// (~Two system clocks after SPI clock edge)
if (!seln_prev && clock_edge)
par_rx <= {par_rx[DW-2:0],mosi};
end
end
assign miso = par_rx[DW-1];
endmodule
/*
*
* Auto generated testbench, generated Wed Jun 20 11:04:23 2018
* post edited
*
*/
module spi_dumb_test;
localparam CLK_PERIOD=100;
localparam DW= 128;
// Usual system signals
reg clk; // system clock
reg reset_n; // system reset
// SPI interface
reg sclk;
reg sel_n;
reg mosi;
wire miso;
// Internal data interface
reg [DW-1:0] par_tx; // Data to transmit
wire [DW-1:0] par_rx; // Data received
wire valid;
integer bit_count;
reg [DW-1:0] master_tx; // Data to transmit
reg [DW-1:0] master_rx; // Data received
initial
begin
// Usual system signals
reset_n = 1'b0;
// SPI interface
sclk = 1'b0;
sel_n = 1'b1;
mosi = 1'b0;
// Internal data interface
par_tx = 'b0;
#(5*CLK_PERIOD) reset_n=1'b1;
#(5*CLK_PERIOD) sel_n = 1'b0;
par_tx = 128'h12345678_11111111_87654321_A5C33C5A;
master_tx = 128'h23242526_34353637_45464748_56575859;
for (bit_count=0; bit_count<128; bit_count=bit_count+1)
begin
#(5*CLK_PERIOD) ;
// Tx & RX master emulation, MS bits first
mosi = master_tx[DW-bit_count-1];
master_rx[DW-bit_count-1] = miso;
sclk = 1'b1;
#(5*CLK_PERIOD) ;
sclk = 1'b0;
end
#(5*CLK_PERIOD) ;
sel_n = 1'b1;
#(50*CLK_PERIOD) $stop;
end
spi_dumb
#( .DW (DW) ) // parameters
spi_dumb_0 (
// Usual system signals
.clk (clk), // system clock
.reset_n(reset_n), // system reset
// SPI interface
.sclk (sclk),
.sel_n (sel_n),
.mosi (mosi),
.miso (miso),
// Internal data interface
.par_tx (par_tx), // Data to transmit
.par_rx (par_rx), // Data received
.valid (valid)
);
// Generate clock.
initial
begin
clk = 1'b0;
forever
#(CLK_PERIOD/2) clk = ~clk;
end
endmodule
Nachbearbeitung 2-7-18: festgestellt, dass Anfangs-End-Paar fehlte.
Das Basys3-Board verfügt über eine USB-zu-UART-Schnittstelle. Verwenden Sie dies, um eine UART-Verbindung mit Ihrem Computer zu implementieren. Ich habe noch keinen Computer mit Windows oder Linux gesehen, der UART über COM/tty nicht unterstützt.
Es gibt eine Reihe von Open-Source-UART-Kernen, aber ich würde raten, sie selbst zu schreiben, die meisten von ihnen sind nicht viel wert und ein UART ist sowieso nicht schwer zu schreiben.
(De)Serialisierung ist dasselbe wie das Füllen/Leeren eines Schieberegisters über den UART.
Papst
HKOB