domingo, 11 de noviembre de 2018

Parallella: FPGA, entrada del hash

Esto no ha resultado particularmente difícil. Aclaro que yo apenas sé VHDL y tengo que hacerlo en Verilog. Aún así, lo miré fijo y salió al primer intento.

Lo que hice fue buscar patrones, reproducirlos y extenderlos.


Preguntémosle a git diff cuál fué el cambio:



Desplacé el registro de salida 8 bytes para darle lugar a REG_INPUT2 e REG_INPUT3 y los demás cambios, no voy a mentir, de algún modo los entiendo pero soy absolutamente incapaz de explicarlos.

Lo que si puedo entender es el programa de test, que ahora toma los valores de la linea de comando, los parsea, escribe en las cuatro direcciones consecutivas de memoria y lee de la última el resultado de la operación.


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


#define REG_INPUT0 0x810f0000
#define REG_INPUT1 0x810f0004
#define REG_INPUT2 0x810f0008
#define REG_INPUT3 0x810f000C
#define REG_OUTPUT 0x810f0010

int main(int argc, char *argv[]) {

    uint32_t data0, data1, data2, data3, rdata;

    data0=strtol(argv[1],0,16);
    data1=strtol(argv[2],0,16);
    data2=strtol(argv[3],0,16);
    data3=strtol(argv[4],0,16);

    e_write(REG_INPUT0,data0);
    e_write(REG_INPUT1,data1);
    e_write(REG_INPUT2,data2);
    e_write(REG_INPUT3,data3);

    e_read(REG_OUTPUT, &rdata);

    printf ("RESULT=%d\n", rdata);        
}




martes, 6 de noviembre de 2018

Parallella: FPGA, plan MD5

Habiendo logrado hacer funcionar un ejemplo básico de FPGA en la parallella, que consiste en escribir en dos posiciones de memoria y leer en otra el resultado de una operación matemática o lógica, rumbo a implementar MD5, corresponde ir modificando el ejemplo.



Partiendo de esta linea en src/accelerator/hdl/accelerator.v

   //(PUT CODE HERE!)
   assign result[31:0] = reg_input0[31:0] + reg_input1[31:0];



tengo que pasarle el hash que espero, de 16 bytes (128 bits). Esos reg_inputX ya son 64 bits, así que necesitaría reg_input2 y reg_input3.

Luego necesito un contador de 0x0000...0000 a 0xFFFF...FFFF, comenzando por 24 bits, 16777216 combinaciones, que es lo que vengo manejando como unidad de cálculo. Si fuera increiblemente veloz, tendría que expandir.

Luego una operación lógica muy sencilla aplicada sobre el contador.

Luego, una comparación de los reg_inputX con la salida de la operación lógica muy sencilla.

Y finalmente, reemplazar la función lógica muy sencilla por el pipeline de MD5



                                          +----------------+ 
                                      (1) |reg_input[127:0]|
                                          +--------+-------+
                                                   |
                                                 /128/
                                                   |    
+-------------+      +----------------+       +----v-----+
|counter[23:0]+-/24/->operación lógica+-/128/->comparador|
+-------------+      |  muy sencilla  |       +----------+
                     +----------------+
(2)                     (3)                       (4)  
                         |
                     evolución
                         |
                         V
                        (5)
            +-----+                        +-----+   
            |stage|                        |stage|
      -/24/->     +-/128/->  .....  -/128/->     |
            |  0  |                        |  63 |
            +-----+                        +-----+

Y eso es todo... no, falta todo el asunto del clocking, parar el contador cuando el comparador de igual y restar al contador la cantidad de etapas en el pipeline para saber cual era el valor originario de la comparación cierta, esto último en la CPU, no es una operación frecuente.
Y además el contador podría implementarse con DSPs, quizás el comparador tambien.
Y además, dependiendo de cuantos recursos queden libres, hacer dos o más calculadores.