-2

[Edited]I'm working on a DMA controller model now and I'm writing 3 processes to work in parallel with the same clock, The two main processes access the same registers but I've made sure that they will never conflict using "if" cases to check for certain values, the first case to clear the data of the registers using "clr" signal the problem here is that the values are always "xxxx" and the If condition in the second process there is always true [edit : the signal 'x' is used to determine whether the if condition is true or false, the output on the waveform is '1' which means that this condition is not the one which make a conflict for data_out , although data_out is still X's , So what's making the conflict ?

library ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.numeric_std.ALL;
ENTITY DMAC_CHANNEL_REG_BANK IS
port(

    clr : IN STD_LOGIC; -- async. clear.
    clk : IN STD_LOGIC; -- clock.
    -- Slave Signals
    HRData : OUT STD_LOGIC_vector(31 downto 0);     -- Data to be READ by the AHB SLAVE INTERFACE
    HWData : in std_logic_vector(31 DOWNTO 0); -- data to be written in the REGISTER from the AHB SLAVE INTERFACE
    HAddr : in std_logic_vector(9 downto 0);    -- Address for the Register to be programmed -- from AHB SLAVE INTERFACE
); 
END DMAC_CHANNEL_REG_BANK;

ARCHITECTURE description OF DMAC_CHANNEL_REG_BANK IS
Component Register32 is
PORT(
input : IN STD_LOGIC_VECTOR(31 DOWNTO 0); -- input.
enable : IN STD_LOGIC; -- Write/enable.
clr : IN STD_LOGIC; -- async. clear.
clk : IN STD_LOGIC; -- clock.
output : OUT STD_LOGIC_vector(31 downto 0)
); -- end of port 
end component;

type Arr40x32 is array (39 downto 0) of std_logic_vector(31 downto 0);
signal data_out : Arr40x32;
signal data_in : STD_LOGIC_vector(31 downto 0);

type State_type_logic is (IDLELOGIC);
signal PresentStateLOGIC, NextStateLOGIC : State_type_logic := IDLELOGIC;
signal C0Config: std_logic_vector(31 downto 0);
signal x : std_logic := '0';

BEGIN   
--CHANNEL 0 REGISTERS--
DMACC0_SRCADD    : Register32 port map (data_in,channel_enable(0),clr,clk,data_out(0));
DMACC0_Config    : Register32 port map (data_in,channel_enable(1),clr,clk,data_out(1));

Logic : process (clk,PresentStateLogic,DMAC_ENABLE)
begin
case PresentStateLogic is 
when IDLELOGIC => 

C0Config <= data_out(1);
--- Cleaning data of the inactive channels

if C0CONFIG(0) = '0' and C0CONFIG(17) = '0' and C0CONFIG(18) = '0' and PresentStateREG /= WRITE1 and clr /= '0' then  -- checking for Enable , Halt , and Active 
data_out(0) <= x"00000000";
else 
 x <= '1';
end if;

end case;
end process Logic ;

process (clk)
begin 
if (rising_edge(clk)) then 
PresentStateREG <= NextStateREG;
PresentStateLogic   <= NextStateLogic;
end if;
end process;
END description;
  • 1
    You might start by posting a minimal example of the sort of code that is causing you problems. – scary_jeff Mar 10 '17 at 15:48
  • 1
    For the question title, see http://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 . For the question bodies, as Jeff says, we'll need to see code to know what you're really asking, so simplify it into a [MCVE] –  Mar 10 '17 at 15:55
  • Besides Brian's link each process that assigns a signal of a resolved type has a driver for that signal. The effective value of the signal is the [resolved](http://stackoverflow.com/search?q=%5Bvhdl%5D+resolution) value of it's drivers, which can produce 'X's. Your if statement sounds like it's testing inequality or relation using std_ulogic positional values (including meta-values). You can use waveform displays troubleshooting 'virtual hardware' before a debugger. Show an MCVe abstracted for size, you may find your problem(s) doing so and your readers won't have to speculate. –  Mar 10 '17 at 21:17
  • sorry for the delay, I wrote the minimal code and included it above,I'm trying to clear the registers data_out() by clearing "clr" bit(active low), when i comment the lines 140 to 145 , everything is good and the registers are cleared, else they are X's – Ahmed Hesham Mar 11 '17 at 15:56
  • This is not minimal: minimal means "just enough code to prove your point or issue". – JHBonarius Mar 13 '17 at 10:57

1 Answers1

1

An MCVe is a bit more.

You're problem isn't Verifiable without a testbench or something like a waveform showing the problem.

However in this case the problem can be found by searching for drivers in your code.

Noting you used positional association in these, there are the right number of associations, and the last value is an output hooked to data_out elements:

--CHANNEL 0 REGISTERS--
DMACC0_SRCADD    : Register32 port map (data_in,channel_enable(0),clr,clk,data_out(0));
DMACC0_DESTADD   : Register32 port map (data_in,channel_enable(1),clr,clk,data_out(1));
DMACC0_LLI   : Register32 port map (data_in,channel_enable(2),clr,clk,data_out(2));
DMACC0_CONTROL   : Register32 port map (data_in,channel_enable(3),clr,clk,data_out(3));
DMACC0_CONFIG    : Register32 port map (data_in,channel_enable(4),clr,clk,data_out(4));

By looking for other drivers by looking for assignment statements we find they're also driven by the Logic process:

data_out(0) <= x"00000000";
data_out(1) <= x"00000000";
data_out(2) <= x"00000000";
data_out(3) <= x"00000000";
data_out(4) <= x"00000000";

Understanding that there are two drivers comes from understanding that an elaborated design model is comprised of processes interconnected by signals.

How those 'X's are generates is due to resolving multiple drivers. It's a complex explanation found in IEEE Std 1076-2008 14.7.2 and 14.7.3 describing detail of execution of a model (14.7).

data_out is declared is declared as a type Arr40x32 which has an element type of std_logic_vector which is a resolved table.

The resolution function for resolving each element of a std_logic_vector is found in the body of package std_logic_vector.

The table it uses for resolution is:

-------------------------------------------------------------------
-- resolution function
-------------------------------------------------------------------
CONSTANT resolution_table : stdlogic_table := (
--      ---------------------------------------------------------
--      |  U    X    0    1    Z    W    L    H    -        |   |
--      ---------------------------------------------------------
        ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
        ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
        ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
        ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
        ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
        ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
        ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' )  -- | - |
    );

For each std_logic element of a std_logic_value the drivers are taken two at a time with a current resolved value and an additional driver value. The two inputs used to select row and column in the above table which will tell you the resolved value of those two signals. That's done for all the drivers for ever std_logic element of a std_logic_vector value in this case.

One of those drivers you've assigned to all '0's with a latch (Logic process). The other driver is the output of a particular Register32. Once the one driver is outputting '0's and the other driver output's a '1' on a Register 32 bit you'll get an 'X'.

You've essentially described something that can be realized in hardware where one solution might be to gate the data_out values to zero at specific times instead of simply shorting two drivers together.

Without an MCVe and seeing your design in action it may not be possible to suggest a proper fix.

  • Okay, now I'm trying to write the best MCVe possible to describe my problem, but I'm facing a problem to identify where the error occur and the code is too complex and long. But let's use the suggested problem as you stated : " One of those drivers you've assigned to all '0's with a latch (Logic process). The other driver is the output of a particular Register32. Once the one driver is outputting '0's and the other driver output's a '1' on a Register 32 bit you'll get an 'X'." Do these drivers interfere with each other even if the case to enter this statement is false? – Ahmed Hesham Mar 14 '17 at 00:21
  • Once a driver drives a value it is used unless the driver is disconnected or the value is updated. All the drivers on a net contribute if it's a resolved type. If not a resolved type it is an error if there's more than one driver, which should tell you to only drive a signal from one process. You have a design problem. –  Mar 14 '17 at 05:46