Hello!
I'm working with a Virtex 5. And I'm getting my "derriere" kicked.
I'm trying to do a count and accumulate variable which is later
converted to a vector and used as an address to a RAM memory. So, the
idea is simple:
- A integer variable (ACC) inside my process is used to count and
accumulate;
- The ACC is casted to STD_LOGIC_VECTOR using addr_source:=
CONV_STD_LOGIC_VECTOR(ACC,32);
- addr_source is copied to an address buffer register. The buffer feeds
my RAM's address buffer.
- libraries used:
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
My code:
1 | fsm_lower_operation: PROCESS (present_state)
|
2 | VARIABLE addr_sink : STD_LOGIC_VECTOR(0 TO data_width - 1) := X"00030005";
|
3 | VARIABLE addr_source: STD_LOGIC_VECTOR(0 TO data_width - 1) := X"00020000";
|
4 | VARIABLE acc : INTEGER RANGE 0 TO 200000;
|
5 | BEGIN
|
6 | CASE present_state IS
|
7 | WHEN get_inst =>
|
8 | AndAddr <= (others => '0');
|
9 | AndDataOut <= (others => '0');
|
10 | next_state <= load_addr_A;
|
11 |
|
12 | WHEN load_addr_A =>
|
13 | AndAddr <= addr_source;
|
14 | AndDataOut <= (others => '0');
|
15 | next_state <= inc_stateA;
|
16 |
|
17 | WHEN inc_stateA =>
|
18 | AndAddr <= (others => '0');
|
19 | AndDataOut <= (others => '0');
|
20 | acc := CONV_INTEGER(addr_source) + 1;
|
21 | addr_source := CONV_STD_LOGIC_VECTOR(acc,32);
|
22 | next_state <= wait_A;
|
23 |
|
24 | WHEN wait_A =>
|
25 | AndAddr <= (others => '0');
|
26 | AndDataOut <= (others => '0');
|
27 | next_state <= getA;
|
28 |
|
29 | WHEN getA =>
|
30 | AndAddr <= (others => '0');
|
31 | AndDataOut <= (others => '0');
|
32 | buff(0) <= AndDataIn;
|
33 | next_state <= load_addr_B;
|
34 |
|
35 | WHEN load_addr_B =>
|
36 | AndAddr <= addr_source;
|
37 | AndDataOut <= (others => '0');
|
38 | next_state <= inc_stateB;
|
39 |
|
40 | WHEN inc_stateB =>
|
41 | AndAddr <= (others => '0');
|
42 | AndDataOut <= (others => '0');
|
43 | acc := CONV_INTEGER(addr_source) + 1;
|
44 | addr_source := CONV_STD_LOGIC_VECTOR(acc,32);
|
45 | next_state <= wait_B;
|
46 |
|
47 | WHEN wait_B =>
|
48 | AndAddr <= (others => '0');
|
49 | AndDataOut <= (others => '0');
|
50 | next_state <= getB;
|
51 |
|
52 | WHEN getB =>
|
53 | AndAddr <= (others => '0');
|
54 | AndDataOut <= (others => '0');
|
55 | buff(1) <= AndDataIn;
|
56 | next_state <= save_result;
|
57 |
|
58 | WHEN save_result =>
|
59 | AndAddr <= addr_sink;
|
60 | AndDataOut <= buff(0) AND buff(1);
|
61 | next_state <= end_state;
|
62 |
|
63 | WHEN end_state =>
|
64 | next_state <= end_state;
|
65 |
|
66 | WHEN OTHERS => NULL;
|
67 | END CASE;
|
68 | END PROCESS fsm_lower_operation;
|
My issue
- When using the ACC process as explained above, operation doesn't work
on hw. Simulating works perfectly.
- If I declare the first address' value as, i.e., X"00020001" and the
next one as X"00002002" (explicit declaration) it works fine in HW and
SW. The problem only occurs when I use a dynamic addressing. Ps. Mind
only 16 MSbits (0001 and 0002); 16 LSBits are used as instructions.
- RAM code is OK. I used ISE template to synthesize my RAM.
- Further information: I'm also using a MicroBlaze. This FSM is part of
a custom IP I'm working on. Communication between uBlaze and IP is based
on PLB V46, using registers. Board ML506 Virtex 5, Xilinx.
- This is driving me crazy. Help.
Thanks!