Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] inout port with value "UUUU.."

Status
Not open for further replies.

Adam Hussey

Junior Member level 3
Joined
Sep 28, 2013
Messages
25
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
276
I find this bizarre because one inout port works just fine (PW), but the other one always reports as uninitialized. The code is for a pipeline processor.

Code:
entity MCProc is
  port (PC, PW, Mem_Bus: inout std_logic_vector (31 downto 0); CLK, Reset: in std_logic);
end entity MCProc;

Architecture First of MCProc is
--
component ALU_32
  port (A_bus, B_bus: in std_logic_vector(31 downto 0); Q_bus: out std_logic_vector(63 downto 0); Opcode: in Popcode; clk, reset: in std_logic);
end component ALU_32;
--
Signal A, B: std_logic_vector (31 downto 0):= (others => '0');
signal Q: std_logic_vector (63 downto 0):=(others => '0');
Signal Instruction: Tinstruction;
Signal Opcode: Popcode;
signal Wrback: bit;

for ALU_32C: ALU_32 use entity work.ALU_32(Behavior);

--INSTRUCTION CYCLE
begin

  ALU_32C: ALU_32 port map (A, B, Q, Opcode, CLK, Reset);

--PControl: Process
P_Fetch: Process
begin
  if (Reset /= '0') then 
    PC <= "00000000000000000000000000000000";
    PW <= "00000000000000000000000000000000";		--Set some initial register values here for simplicity & demonstration.
    Regfile(0) <="00000000000000000000000000000000";	--Register 0 gets the value '0'
    Regfile(1) <="00000000000000000000000000000111";	--Register 1 gets the value '7'
    Regfile(2) <="00000000000000000000000000101101";	--Register 2 gets the value '45'
    Regfile(3) <="00000000000000000000010000000000";	--Register 3 gets the value '1024'
    Regfile(4) <="00000000010001011010001000000000";	--Register 4 gets the value '4563456'
    Regfile(5) <="00000000000101010101010101001101";	--Register 5 gets the value '1398093'
  end if;
  wait until (Reset = '0' and CLK'event and CLK='1');
  PW <= Memory(CONV_INTEGER(PC));
  PC <= PC + 1;
end Process;


if you need more code let me know.


Thanks!
 

Ooooo, lots of problems.

1) can't use "wait until" in operational code, only in testbenches.
2) That construct " wait until (Reset = '0' and CLK'event and CLK='1')" is terrible; I don't even know where to begin.
3) What happens to all your stuff when Reset='0'?? It's undefined==>U U+1=U!!!
 
Ooooo, lots of problems.

1) can't use "wait until" in operational code, only in testbenches.
2) That construct " wait until (Reset = '0' and CLK'event and CLK='1')" is terrible; I don't even know where to begin.
3) What happens to all your stuff when Reset='0'?? It's undefined==>U U+1=U!!!

Sorry I should mention I have never been taught vhdl but was expected to use it. I never claim to be good at it, which is why I'm here requesting help.

I'm not sure what you mean "I can't use it"? It compiles and works find in simulation.
When reset does not = 0, everything that's outside of the
Code:
if (Reset /= '0') then
runs.

Thanks for the help, but I'm not sure this solved my number one problem at the moment..
 

If you are expecting to put this code into an FPGA, you can't use those type of constructs; the tools won't let you.

The reason this is bad form is because you are using combinatorial logic along with synchronous (sort of) logic .

Your basic question was 'why is PC uninitialized?' I think I answered that. Here's what I think is happening in your code:

It looks to see if Reset/=0. If it's not, it just falls through to the wait statement and PC never gets initialized.
 
  • Like
Reactions: S.P.S

    S.P.S

    Points: 2
    Helpful Answer Positive Rating
If you are expecting to put this code into an FPGA, you can't use those type of constructs; the tools won't let you.

The reason this is bad form is because you are using combinatorial logic along with synchronous (sort of) logic .

Your basic question was 'why is PC uninitialized?' I think I answered that. Here's what I think is happening in your code:

It looks to see if Reset/=0. If it's not, it just falls through to the wait statement and PC never gets initialized.

I see what you're saying, but right off the bat the reset signal does not equal = 0. Therefore the code does run through, and all the values set correctly (including PW) except for the PC.
 

I suppose you used inout so you could "read" the value of PC in your code. Instead you should use something like this snippet.

Code VHDL - [expand]
1
2
3
4
5
6
signal PC_int : std_logic_vector (31 downto 0);
...
PC_int <= PC_int + 1;
PW <= Memory(CONV_INTEGER(PC));
...
PC <= PC_int;  -- assign the PC_int to the output port


and make all your inout ports into output ports. It's a bad practice to use inout when what you really want is an output port that you can "read" inside your architecture.
 

    V

    Points: 2
    Helpful Answer Positive Rating
I suppose you used inout so you could "read" the value of PC in your code. Instead you should use something like this snippet.

Code VHDL - [expand]
1
2
3
4
5
6
signal PC_int : std_logic_vector (31 downto 0);
...
PC_int <= PC_int + 1;
PW <= Memory(CONV_INTEGER(PC));
...
PC <= PC_int;  -- assign the PC_int to the output port


and make all your inout ports into output ports. It's a bad practice to use inout when what you really want is an output port that you can "read" inside your architecture.

Ahh good idea I will try that!
 

BTW using PC_int + 1 when PC_int is std_logic_vector is frowned upon as it means you are using the std_logic_arith package that has been deprecated (non IEEE standard). You should really switch to the IEEE package numeric_std.
 

BTW using PC_int + 1 when PC_int is std_logic_vector is frowned upon as it means you are using the std_logic_arith package that has been deprecated (non IEEE standard). You should really switch to the IEEE package numeric_std.

I'm actually not using that package anymore, does this mean I need a new way to add the '+ 1' ?
 

BTW using PC_int + 1 when PC_int is std_logic_vector is frowned upon as it means you are using the std_logic_arith package that has been deprecated (non IEEE standard). You should really switch to the IEEE package numeric_std.

Using std_logic_vector doesn't require std_logic_arith; it works perfectly fine with numeric_std.
 


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
begin
  if (Reset /= '0') then 
    PW <= "00000000000000000000000000000000";       --Set some initial register values here for simplicity & demonstration.
--  PC <= "00000000000000000000000000000000";   
    Regfile(0) <="00000000000000000000000000000000";    --Register 0 gets the value '0'
    Regfile(1) <="00000000000000000000000000000111";    --Register 1 gets the value '7'
    Regfile(2) <="00000000000000000000000000101101";    --Register 2 gets the value '45'
    Regfile(3) <="00000000000000000000010000000000";    --Register 3 gets the value '1024'
    Regfile(4) <="00000000010001011010001000000000";    --Register 4 gets the value '4563456'
    Regfile(5) <="00000000000101010101010101001101";    --Register 5 gets the value '1398093'
  end if;
  if (Reset = '0' and CLK'event and CLK='1') then
    PW <= Memory(CONV_INTEGER(s_PC));
    s_PC <=  s_PC + 1;
    PC <= s_PC; wait for 10ps;
  end if;
end Process;
                                
P_Decode: Process(s_PC)
begin
  If reset='0' and clk='1' then
    Instruction <= to_record (PW); --wait for 10 ps;
    Opcode <= Instruction.opcode; --wait for 10 ps;
  end if;
end Process;
 
P_Execute: Process(Instruction)
 variable temp: std_logic_vector (15 downto 0):= (others => '0');
begin
 If reset='0' and clk='1' then
   B <= Regfile(CONV_INTEGER(Instruction.Rt));                     
   case Opcode is
     when MSLL => A(4 downto 0) <= Instruction.SHAMT;
      A(31 downto 5)<= (others => '0');
         Wrback <= '1';
     when MSRL => A(4 downto 0) <= Instruction.SHAMT;
       A(31 downto 5)<= (others => '0');
         Wrback <= '1';
     when JR =>   s_PC  <= Regfile(CONV_INTEGER(Instruction.Rs));
          Wrback <= '1';
     when LW =>   temp := (Instruction.Rs) + (Instruction.Immed);
             Wrback <= '1';
       Regfile(CONV_INTEGER(Instruction.Rt)) <= Memory(CONV_INTEGER(temp));
     when SW =>   temp := (Instruction.Rs) + (Instruction.Immed);
      Memory(CONV_INTEGER(temp)) := Regfile(CONV_INTEGER(Instruction.Rt));
                      Wrback <= '1';
     when JUMP => s_PC(25 downto 0) <=  Instruction.Address;
                      Wrback <= '1';
     when beq => if (Regfile(CONV_INTEGER(Instruction.Rs)) = Regfile(CONV_INTEGER(Instruction.Rt))) then 
                  s_PC(15 downto 0) <= s_PC(15 downto 0) + std_logic_vector(-1 + signed(Instruction.Immed)); 
                end if;
            Wrback <= '1';
     when bne => if (Regfile(CONV_INTEGER(Instruction.Rs)) /= Regfile(CONV_INTEGER(Instruction.Rt))) then 
                  s_PC(15 downto 0) <= s_PC(15 downto 0) + std_logic_vector(-1 + signed(Instruction.Immed));
            end if;
            Wrback <= '1';
     when others => A <= Regfile(CONV_INTEGER(Instruction.Rs));
          Wrback <= '1';
   end case;
   PC <= s_PC;
 end if; 
end process;
 
P_WriteBack: Process(Wrback)
begin
 If reset='0' and clk='1' then
  if (Wrback = '1') then
    Regfile(CONV_INTEGER(Instruction.Rd)) <= Q(31 downto 0);
  end if;
 end if;
end Process;



Ok, so why now am i getting an 'X' in the s_PC signal? I'm not seeing any conflicts here..
It happens after the fetch process and before the decode process :?:
 
Last edited:

You still need to address issues like.


Code VHDL - [expand]
1
if (Reset = '0' and CLK'event and CLK='1') then


and

Code VHDL - [expand]
1
If reset='0' and clk='1' then



I'm not even sure if a synthesis tool will be able to correctly interpret the first one. The second one will result in a gated clock (perhaps even a latch), which will result in implementation difficulties in an FPGA.

Even if this is simulation only code (e.g. testbench and models) it would be better if you stuck to traditional clocked process structure.

It looks as if you've just jumped head first into the project coding without having first read a book or an online tutorial on VHDL. I suggest you go back and read a book/online on VHDL. Looking at your code again, I suspect you have a SW background as what you've written has a very software like structure to it. Unless you are just a modeling engineer, creating models for use in a testbench, you should change your approach and design the circuit first then translate it to VHDL (i.e. design the processing pipeline).

Here are some examples of VHDL representing various digital hardware logic blocks.
**broken link removed**
If you look at the "register" one you'll notice that it's structured differently than what you wrote.

Regards
 
Last edited:

Sorry I thought this was solved, but even after I made the PC an 'out', I still can't even assign values to it.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
PW <= Memory(CONV_INTEGER(s_PC));
    s_PC <=  s_PC + 1;
    PC <= s_PC;
    decodeReady <= '1', '0' after 5 ps;
end Process;
                                
P_Decode: Process(s_PC)
begin
  If reset='0' and clk='1' and decodeReady = '1' then
    Instruction <= to_record (PW); --wait for 10 ps;
  end if;
end Process;
 
 
  
 P_Execute: Process(Instruction)
 variable temp: std_logic_vector (15 downto 0):= (others => '0');
 begin
  If reset='0' and clk='1' then
   B <= Regfile(CONV_INTEGER(Instruction.Rt));  
   Opcode <= Instruction.opcode;
   WrRdy <= not WrRdy;
   case Instruction.Opcode is
    when MSLL => A(4 downto 0) <= Instruction.SHAMT;
      A(31 downto 5)<= (others => '0');
    Wrback <= '1';
    when MSRL => A(4 downto 0) <= Instruction.SHAMT;
    A(31 downto 5)<= (others => '0');
     Wrback <= '1';
    when JR =>   PC  <= Regfile(CONV_INTEGER(Instruction.Rs));
      Wrback <= '0';
    when LW =>   temp := (Instruction.Rs) + (Instruction.Immed);
          Wrback <= '0';
   Regfile(CONV_INTEGER(Instruction.Rt)) <= Memory(CONV_INTEGER(temp));
    when SW =>   temp := (Instruction.Rs) + (Instruction.Immed);
      Memory(CONV_INTEGER(temp)) := Regfile(CONV_INTEGER(Instruction.Rt));
                  Wrback <= '0';
    when JUMP => PC(25 downto 0) <=  Instruction.Address;
                  Wrback <= '0';
    when beq => if (Regfile(CONV_INTEGER(Instruction.Rs)) = Regfile(CONV_INTEGER(Instruction.Rt))) then 
                   PC(15 downto 0) <= s_PC(15 downto 0) + std_logic_vector(-1 + signed(Instruction.Immed)); 
                end if;
        Wrback <= '0';
    when bne => if (Regfile(CONV_INTEGER(Instruction.Rs)) /= Regfile(CONV_INTEGER(Instruction.Rt))) then 
                  PC(15 downto 0) <= s_PC(15 downto 0) + std_logic_vector(-1 + signed(Instruction.Immed));
        end if;
        Wrback <= '0';
    when others => A <= Regfile(CONV_INTEGER(Instruction.Rs));
      Wrback <= '1';
   end case;
  end if; 
 end process;
 
P_WriteBack: Process(Q)
begin
 If reset='0' and clk='1' then
  if (Wrback = '1') then
    Regfile(CONV_INTEGER(Instruction.Rd)) <= Q(31 downto 0);
    --Wrback <= '1';
  end if;
 end if;
end Process;



PC is still never changing from 'UUU' value.
Another problem I'm having is that signals 'A' and 'B' are giving me the same problem, thus never allowing the ALU to activate.

This really makes no sense, as I did a very similar project that was a non-pipeline processor vhdl implementation, where everything worked flawlessly. All of a sudden now I convert one process to 4 processes and everything falls apart.

Thanks
 

i assume its due to incorrect sensitivity lists.
This is still code that will not compile for real hardware.
 

Re: inout port with value &quot;UUUU..&quot;

i assume its due to incorrect sensitivity lists.
This is still code that will not compile for real hardware.

Could you elaborate on that? how are the sensitivity lists 'incorrect' ?

I understand that it will not compile for real hardware, and if possible, ignore that for now. The primary objective here is to get code that simulates and will get me a good enough grade:razz: Once I understand whats causing simulation to fail we can work on working with real hardware. With this being due next week, I don't want to make drastic changes.
 

Ok:

the P-decode process is missing clk, reset, decodeReady and PW. I dont know why you have s_PC in the sensitivity list as it's not used in the process.
P_execute is missing clk, reset, regfile, wrrrdy, memory and s_PC.

You have not used the proper synchronous template.

This all assumes you want your simulation to behave the way the real hardware would. Otherwise, if you dont mind the code having no relation to the real hardware, carry on.
 

Adam,

You're being way too stubborn. Everyone here has been trying to help you write code that correctly simulates and synthesizes to hardware. If you had used a standard register process template you would probably have had less issues. In the last 3 days you could have easily redone the code to use the correct clocked process template and saved yourself headaches.

Your problems probably stem from the gated clocks you are using and the fact you are probably getting some strange behavior as your clock is really a latch enable.

Regards
 

Ok:

the P-decode process is missing clk, reset, decodeReady and PW. I dont know why you have s_PC in the sensitivity list as it's not used in the process.
P_execute is missing clk, reset, regfile, wrrrdy, memory and s_PC.

You have not used the proper synchronous template.

This all assumes you want your simulation to behave the way the real hardware would. Otherwise, if you dont mind the code having no relation to the real hardware, carry on.

To be honest, I didn't realize the process sensitivity list had to have certain values that were used. I'll try to explain my reasoning. Basically I wanted the decode stage to be active whenever the PC was updated with a new instruction. Same for the execute stage, I want that to be used when an instruction has been decoded. In simulation it works this way, is this not the correct way to go about the sensitivity list?

Thanks.

Adam,

You're being way too stubborn. Everyone here has been trying to help you write code that correctly simulates and synthesizes to hardware. If you had used a standard register process template you would probably have had less issues. In the last 3 days you could have easily redone the code to use the correct clocked process template and saved yourself headaches.

Your problems probably stem from the gated clocks you are using and the fact you are probably getting some strange behavior as your clock is really a latch enable.

Regards

I'm sorry, I did not know of any templates before now.
On the clock: are you saying my clock isn't edge triggered? or that the processes don't depend on the clock? I'll try to mess with the sensitivity lists and I'll report back.
Thanks again
 

Your clocks are all level sensitive and they are gated. To have edge sensitive clocks you should only have the clock in the if statement.

if rising_edge(clk) then

That will give you an edge triggered process.

Regards
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top