elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Informática
| |-+  Electrónica
| | |-+  Reusing registers in VHDL FSM
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Reusing registers in VHDL FSM  (Leído 5,142 veces)
Darian

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Reusing registers in VHDL FSM
« en: 3 Julio 2019, 17:22 pm »

Hello,

I need to write a Finite State Machine (FSM) in VHDL code and  want to have several computations being processed at the same time (a standard pipeline). In every state I have several operations to be calculated and I employ registers for the result of each one. I strongly need to reuse these registers, for example: Register 1 is filled in State 1 (as a result of a multiplication) and it is used in the State 2 and State 3 (as parameter of other operations), then in the State 4, I want to save a new operation result (another multiplication) in Register 1 reusing it.

My code works in Simulation in Xilinx Vivado 2019, but when I implement the desing in a real FPGA (Basys 3 Artix-7) it doesn't work. I realized that the problem is that the correct values are not saved when I reuse the registers. Sometimes, the first time I reuse them, they keep the correct value, but already in the second reuse in later FSM states, the stored values are not correct, I mean, they do not correspond to the result of the operation that I am trying to save in the register.

Next, an example of my FSM design:

Código
  1. LIBRARY IEEE;
  2. USE IEEE.std_logic_1164.all;
  3. USE IEEE.numeric_std.ALL;
  4.  
  5. ENTITY test1_arith IS
  6. GENERIC (
  7.    ap_bit_width : positive := 4;
  8.    ap_latency : positive := 2
  9. );
  10. PORT (
  11.    I1 : IN STD_LOGIC_VECTOR(ap_bit_width - 1 downto 0);
  12.    I2 : IN STD_LOGIC_VECTOR(ap_bit_width - 1 downto 0);
  13.    I3 : IN STD_LOGIC_VECTOR(ap_bit_width - 1 downto 0);
  14.    O1 : OUT STD_LOGIC_VECTOR(ap_bit_width - 1 downto 0);
  15.    ap_clk : IN STD_LOGIC;
  16.    ap_rst : IN STD_LOGIC;
  17.    ap_start : IN STD_LOGIC;
  18.    ap_done : OUT STD_LOGIC;
  19.    ap_idle : OUT STD_LOGIC;
  20.    ap_ready : OUT STD_LOGIC
  21. );
  22. END;
  23.  
  24. ARCHITECTURE test1_arith_arch OF test1_arith IS
  25.    ATTRIBUTE CORE_GENERATION_INFO : STRING;
  26.    ATTRIBUTE CORE_GENERATION_INFO OF test1_arith_arch : ARCHITECTURE IS "Test,VHDLbyMOEA,{HLS_SYN_LAT=2}";
  27.    CONSTANT ap_const_logic_1 : STD_LOGIC := '1';
  28.    CONSTANT ap_const_logic_0 : STD_LOGIC := '0';
  29.    TYPE state IS (state_1,state_2,state_3);
  30.    SIGNAL state_present: state;
  31.    SIGNAL state_future: state;
  32.    SIGNAL Flag: Integer:=0;
  33.     --Signal RF : STD_LOGIC_VECTOR_array;
  34.    FUNCTION ALU ( Op: IN integer range 0 TO 23;
  35.     A, B: IN STD_LOGIC_VECTOR (ap_bit_width - 1 downto 0) )
  36.    RETURN std_logic_vector is variable Result : std_logic_vector(ap_bit_width - 1 downto 0);        
  37.  
  38.    variable A_int: Integer:=0;
  39.    variable B_int: Integer:=0;
  40.    variable Result_int: Integer:=0;
  41.    begin
  42.    A_int := to_integer(unsigned(A));
  43.    B_int := to_integer(unsigned(B));
  44.    With Op Select Result_int:=
  45.        to_integer(unsigned(NOT A)) When 0,
  46.        to_integer(unsigned(A AND B)) When 1,
  47.        to_integer(unsigned(A OR B)) When 2,
  48.        to_integer(unsigned(A NAND B)) When 3,
  49.        to_integer(unsigned(A NOR B)) When 4,
  50.        to_integer(unsigned(A XOR B)) When 5,
  51.        to_integer(unsigned(A XNOR B)) When 6,
  52.        (A_int + B_int) When 7,
  53.        (A_int - B_int) When 8,
  54.        (A_int * B_int) When 9,
  55.        (A_int / B_int) When 10,
  56.        ABS(A_int) When 11,
  57.        (A_int ** B_int) When 12,
  58.        (A_int MOD B_int) When 13,
  59.        to_integer(unsigned(A) & unsigned(B)) When 14,
  60.        to_integer(unsigned(A) SLL B_int) When 15,
  61.        to_integer(unsigned(A) SRL B_int) When 16,
  62.        to_integer(unsigned(A) SLA B_int) When 17,
  63.        to_integer(unsigned(A) SRA B_int) When 18,
  64.        to_integer(unsigned(A) ROL B_int) When 19,
  65.        to_integer(unsigned(A) ROR B_int) When 20,
  66.        to_integer(unsigned(A) & unsigned(B)) When 21,
  67.        to_integer(unsigned(A) & unsigned(B)) When 22,
  68.                 0   When others;
  69.    return STD_LOGIC_VECTOR (TO_UNSIGNED (Result_int, (ap_bit_width)));
  70.    END FUNCTION;
  71.  
  72.    SHARED VARIABLE R1:std_logic_vector(ap_bit_width - 1 downto 0);    
  73.  
  74.  
  75.    BEGIN
  76.  
  77.    OP_FSM : PROCESS (state_present)
  78.  
  79.     BEGIN
  80.    CASE state_present IS
  81.  
  82.    WHEN state_1=>
  83.    R1 := ALU(Op => 7 ,A => I1,B => I2);
  84.    Flag<=1;
  85.    IF (Flag=1) THEN
  86.    state_future <= state_2;
  87.    END IF;
  88.  
  89.    WHEN state_2=>
  90.    R1:= ALU(Op => 7 ,A => R1, B => I3);
  91.    Flag<=2;
  92.    IF (Flag=2) THEN
  93.    state_future <= state_3;
  94.    END IF;
  95.  
  96.    WHEN state_3=>
  97.    O1<= ALU(Op => 7 ,A => R1,B => "0001");
  98.    Flag<=3;
  99.    IF (Flag=3) THEN
  100.    state_future <= state_1;
  101.    END IF;
  102.    END CASE;
  103.    END PROCESS OP_FSM;
  104.  
  105.    CLK_FSM : PROCESS (ap_clk)
  106.    BEGIN
  107.    IF (ap_clk = '1' AND ap_clk'EVENT) THEN
  108.    state_present <= state_future;
  109.    END IF;
  110.    END PROCESS CLK_FSM;
  111.  
  112. END test1_arith_arch;

In this case, I want to reuse R1 and it works well in Simulation with Xilinx Vivado (1 + 4 + 0 + 1 = 6).

Unfortunately, in the Basys 3 FPGA Artix-7 I don't get the correct results. In the Case 10 in a FPGA, it should get 6 (1 + 4 + 0 + 1) as result, but it gets 14 instead.

In the tests that I have been doing I realized that it works better when before assigning a new value in the registry the value of the record is made zero before reassigning a value, for example:

Código
  1. WHEN state_3=>
  2.    R4<="0000"
  3.    IF( R4 = "0000") then
  4.    R4<= ALU(Op => 7 ,A=> R2,B=> R3, C =>"0000");
  5.    Flag <=3;
  6.    IF (Flag =3) THEN
  7.    state_future <= state_4;
  8. END IF;
  9. END IF;

Using this form I can reuse a register once, the second time I want to reassign a value to the register, incorrect values are shown in the output.

I declarated the registers as SHARED VARIABLE and SIGNALS and I have the same problem with both.

I appreciate any suggestion or idea, thanks a lot.


En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Evitar que te borren los Debug registers en un debugger ring3
ASM
biribau 3 3,486 Último mensaje 18 Junio 2009, 16:41 pm
por biribau
VHDL
Electrónica
ukol 6 11,826 Último mensaje 7 Enero 2019, 01:30 am
por mochilera
Programacion en VHDL
Programación General
Fox_Neo 1 5,225 Último mensaje 10 Octubre 2013, 17:44 pm
por Fox_Neo
VGA en VHDL
Foro Libre
joan.ayala 0 2,055 Último mensaje 23 Mayo 2014, 22:52 pm
por joan.ayala
VHDL
Electrónica
carlospulido3 2 5,878 Último mensaje 27 Enero 2019, 16:08 pm
por andresiniesta
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines