¿Cómo puedo asignar una entrada de std_logic_vector de 256 bits?

1

Me di cuenta de un algoritmo AES-256 que cifra un std_logic_vector de 128 bits (plain_text) con un std_logic_vector de 256 bits (master_key). Hice un banco de pruebas para verificar el comportamiento del proceso de encriptación, y ahora me gustaría implementar este algoritmo en mi placa Basys3 (uso Vivado como IDE). Mis preguntas son:

¿Cómo puedo mapear los vectores de entrada? ¿Debo declarar señales en mi arquitectura, sabiendo que no tengo suficientes puertos de E / S?

    
pregunta Cedric

2 respuestas

2

Una interfaz serial usa la menor cantidad de pines. De todas las interfaces seriales, SPI es la más fácil de implementar. (Creo que se trata de cinco líneas de código). Como una interfaz SPI transmite y recibe datos al mismo tiempo, también puede usarlos para leer el resultado.

Bien, acabo de intentarlo y era un poco más de cinco líneas que trataban principalmente de la sincronización de las señales SPI a un reloj del sistema (frecuencia interna más alta)

El siguiente código fue pirateado rápidamente y parece funcionar:

//
// 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

Edición de publicación 2-7-18: se encontró que faltaba comenzar el par final.

    
respondido por el Oldfart
0

La placa Basys3 tiene una interfaz USB a UART. Use esto para implementar un enlace UART con su computadora. Todavía no he visto una computadora con Windows o Linux que no admita UART a través de COM / tty.

Hay una serie de núcleos UART de código abierto, pero yo recomendaría escribirlo usted mismo, la mayoría de ellos no valen mucho y de todos modos no es difícil escribir un UART.

(De) serializar es lo mismo que llenar / vaciar un registro de desplazamiento sobre el UART.

    
respondido por el DonFusili

Lea otras preguntas en las etiquetas