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:

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): Figure 1. Unfortunately, in the Basys 3 FPGA Artix-7 I don't get the correct results: Figure 2. In this figure, I show the Case 10 in a FPGA, it should get 6 (1 + 4 + 0 + 1) as result, but it gets 14 instead: Figure 3. 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:

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.