Wie kann ich einen 256-Bit-Eingang std_logic_vector zuweisen

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?

Wie kommt der 128-Bit-Klartext-Vektor in das FPGA?
Erstellen Sie eine serielle Kommunikationsschnittstelle (z. B. USB, SPI, I2C usw.), um in Register auf Ihrem FPGA zu schreiben.

Antworten (2)

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.

Dies sollte natürlich kein Thread zum Vergleich aller seriellen Protokolle werden, aber der Grund, warum ich SPI Anfängern nicht raten würde, ist, dass die Welt immer noch nicht entschieden hat, was das SPI-Protokoll ist. Es würde funktionieren, erfordert aber mehr Fummelei als andere, standardisiertere Protokolle. Außerdem: Wenn Sie es auf einfache, knappe Weise schreiben, führt dies tendenziell zu Übergängen in der Taktdomäne. Das alles gesagt: +1, natürlich.
Ich habe angefangen, einen zu schreiben, und habe meine Antwort aktualisiert. Ich kann den Code posten, sobald er verifiziert ist. (Das dauert 10x länger als das Schreiben des Codes)
Vielen Dank, ich schätze Ihre Hilfe. Ich werde nach weiteren Informationen über SPI suchen!

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.

Vielen Dank für Ihre Antwort, dann werde ich anfangen zu studieren, wie UART funktioniert!