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

Status
Not open for further replies.
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

Does this mean remove the "reset ='0' " ? I tried changing to that and I still can't seem to change the ALU's A and B values, nor the PC's values.
 

I highly suggest using the correct process templates for synchronous description:

Code:
process(clk, reset)  -- reset only needed if it is asynchronous
begin
  if reset = '1' then
    --do async reset here
  elsif rising_edge(clk) then
    --synchronous code goes here
  end if;
end process;

The reason you think your code works is that processes are only re-activated when a signal in the sensitivity list changes. Putting a signal in there that isnt even in the process makes it appear that you may be "clocking" the data, or making other things change only when you want them to, but in synthesis the sensitivity list is ignored and the logic is created only from the code inside the process. This is why you need to follow the correct templates from the start, or you end up having to re-write the lot when you want to put it in an FPGA.

There are plenty of textbooks and tutorials on the web about VHDL for logical design.
 



Ok, so I believe I have the correct implementation now..


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
72
73
74
75
76
77
P_Fetch: Process (CLK)
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 rising_edge(CLK)) then
    PW <= Memory(CONV_INTEGER(s_PC));
    s_PC <=  s_PC + 1;
    PC <= s_PC;
    decodeReady <= '1', '0' after 15 ps;
  end if;   
end Process;
                                
P_Decode: Process(CLK)
begin
  If reset='0' and rising_edge(CLK) and decodeReady = '1' then
    Instruction <= to_record (PW); --wait for 10 ps;
    exReady <= '1', '0' after 15 ps;
  end if;
end Process;
 
 
  
 P_Execute: Process(CLK)
 variable temp: std_logic_vector (15 downto 0):= (others => '0');
 begin
  If reset='0' and rising_edge(CLK) and exReady = '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(CLK)
begin
 If reset='0' and rising_edge(CLK) then
  if (Wrback = '1') then
    Regfile(CONV_INTEGER(Instruction.Rd)) <= Q(31 downto 0);
    --Wrback <= '1';
  end if;
 end if;
end Process;



Still cannot write to A, B, or PC. Again, it is very irritating why the PW works fine, but the PC is always uninitialized.
 

Tricky showed exactly what to do and you did exactly something different.

You have a LOT of errors/problems. Here are a few:

1) You need to have an IF/ELSIF construct, not a whole bunch of if statements.
2) If you have an "if reset.. " statement, you don't want (or need) an "if reset ='0' and rising_edge(clk)". That's a gated clock.
3) You can't use an "after 15 ps" statement except in a testbench.
4) In your first process, you assign decodeready after the clock statement, but what happens to it when reset occurs? (Answer: indeterminate)
 
Adam,

Barry and Tricky have both shown you multiple problems with your code. You keep refusing to change your code to use the correct templates for synthesizable VHDL code. On multiple occasions you've stated that your code is mostly working (in simulation), but doesn't update signal xxx properly and that changing it to use a proper template isn't important right now just fixing the update problem on those signals is important so you can hand your project in.

You've missed the point of your "project" it's not about handing in something that works in simulation (but isn't synthesizable or may not even work using another simulator). It's likely more about correctly using VHDL to model something. You can write models that are or are not synthesizable, either model is valid depending on the circumstances and when/how it is used. What you've written so far isn't even an accurate model.

The project you are trying to "fix" would result in an F grade, in my opinion, regardless of it simulating correctly and generating all the outputs. As written your code displays a complete misunderstanding of how to write VHDL processes. On a job interview if they ask you to write VHDL code for a resetable register with enable and you wrote down what you've posted. I would consider the interview to be over.

You should spend some time reading online VHDL tutorials. Many of them show examples of how to code registers/multiplexers/decodes/shifts etc.

Regards
 


With all respect, this isn't a class about learning vhdl, or even a class where knowledge of vhdl is a prerequisite. I understand that your patience are running out, but try to understand where I'm coming from. Everything that you said needs changing I have changed as far as I'm concerned. Please understand that I have other classes, including finals coming up, and reading several vhdl tutorials and understanding them is time consuming and difficult. You continue to say I'm not changing things, but you don't mention what.
Please forgive my lack of knowledge but try to work with me here. I'll post back after I make changes that Barry has provided.

Thanks
 

If VHDL wasn't a prerequisite, why would you try to learn it "on-the-fly" for a project prior to final exams? You should have used a language you were already familiar with.
 

If VHDL wasn't a prerequisite, why would you try to learn it "on-the-fly" for a project prior to final exams? You should have used a language you were already familiar with.

I agree, the professor should probably lose his job. I literally needed to learn it on the fly throughout the semester
 

So the professor didn't specify that VHDL would be a requirement and the class wasn't a learning VHDL class. That professor is probably an example of how tenure is a bad thing.

Regardless I suggest you use the standard templates, you can look at the site with examples I posted in #13.


Regards
 


Yes it was so bad that people would get a passing grade if their code compiled successfully.

You guys did not mention (I don't think) about async vs syn reset processes....

Based off of this post , does this code work?


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
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'
  
  elsif rising_edge(CLK) then
    PW <= Memory(CONV_INTEGER(s_PC));
    s_PC <=  s_PC + 1;
    --PC <= s_PC;
    decodeReady <= '1';
  end if;   
end Process;
                                
P_Decode: Process(CLK)
begin
  If rising_edge(CLK) then
    If reset='0' and decodeReady = '1' then
      Instruction <= to_record (PW); --wait for 10 ps;
      exReady <= '1';
    End if;  
  end if;
end Process;



My guess is no, as the same problems still exist.
 
Last edited:

For sync resets, the reset will only occur on a clock edge.
For async resets, the reset occurs as soon as the reset signal goes high.

THe problem with async resets, if they are connected to a truly async source (like a push button), when it comes out of reset it could then violate the setup and hold time of the register. So async resets are best avoided if they are truely asynchronous. If you synchronise the source reset, and connect it to the async resets of the registers, thats safe (and recommended in altera devices, as sync resets have to be emulated with a mux).

It is a massive improvement - it now uses the correct templates.
Now it is your job to debug why it doesnt work.
 


Thank you. No disrespect, but the reason I started this topic was for help on why it doesn't work. If I knew at all how to debug this, I wouldn't be here.

Please, if you see the problem, let me know.
 

s_PC isn't in the reset condition therefore it will have no initial value
Regfile isn't even used in the clocked portion of the IF, where is it used? If it's used in a different process then you need to remove it and put it in that other process.
PC also isn't used in this process.
decodeReady starts off U or X and then gets set to 1 permanently, don't you want it to return to 0 at some point?

exReady will start out U or X and then will transition to 1 forever once the if condition is met. Don't you want it to go low again?
PW will always be X as the PW in the first process will never be valid.

You should post all the code so we can look at more of the interaction between processes.

Regards,
 

Ok, thanks I have fixed the PC and Regfile (Progress!). As far as those signals go, yes, I just haven't gotten to implement those yet.
The last problem comes from trying to write to the ALU (A & B)


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
entity MCProc is
  port (PC: out std_logic_vector (31 downto 0); PW: 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 s_PC: std_logic_vector (31 downto 0):=(others => '0');
Signal Instruction: Tinstruction;
Signal Opcode: Popcode;
signal Wrback: bit;
signal WrRdy: bit := '0';
signal decodeReady, exReady: bit := '0';
--Signal STATE: PSTATE;
 
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 (CLK)



the execute process:

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
P_Execute: Process(CLK)
 variable temp: std_logic_vector (15 downto 0):= (others => '0');
 begin
  If reset='0' and rising_edge(CLK) and exReady = '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;



I wasn't sure if you wanted the ALU code, as it doesn't get that far but heres the entity

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
entity ALU_32 is
  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 entity ALU_32;
--
architecture Behavior of ALU_32 is
signal Overflow: std_logic;
--
begin 
--
ALU_Exec: process(CLK)

 

I would start by making PW an in or an out. Inouts are only there for tri-state buffers and you only have those in FPGAs on the pins of the device. Internal connections should be in or out only. But from the code you've posted, I cannot see it used anywhere anyway.

Now we've given you instruction for the above code, you should be able to apply it all to your p_execute process.
 


I'm not sure what you mean here...there are no inouts in that process. This is due today so I really need to get this ALU working.

Thanks
 

In the MCPRoc entity, there is PW, which is set to inout. I cannot see it used.

The process need mods in the same way you modified the other code - separate the clock and resets.,
 

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

Sorry I just didn't include the code where the PW was used, but it does in fact have quite an important use


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
begin
  if (Reset /= '0') then 
        PW <= "00000000000000000000000000000000";  --HERE
--  PC <= "00000000000000000000000000000000";     
  elsif rising_edge(CLK) then
    if (dojump = '1') then
      s_PC <= PC;
    else
      s_PC <=  s_PC + 1;
    end if;
           PW <= Memory(CONV_INTEGER(s_PC));  --Here
    decodeReady <= '1'; 
  end if;   
end Process;




Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
P_Decode: Process(CLK)
begin
  If rising_edge(CLK) then
    If reset='0' and decodeReady = '1' then
       Instruction <= to_record (PW); -- function translates Program Word into decoded instruction
      exReady <= '1';
    End if;  
  end if;
end Process;



- - - Updated - - -

Update: I have figured out that it is the Regfile that is writing "U's" to the ALU, so I need to figure out what is wrong with that.
Update2: I'm an idiot, I defined Regfile in the wrong spot... I fixed that, updated the reset condition for it, and now everything works that didn't work before.

Big thanks to everyone that helped. Couldn't have done it without you. Not a moment too soon I might add etiher ;-)
 
Last edited:

based on the two code snippets you should define a PW_int and use that instead. Then you add a PW <= PW_int and change PW to an output on the entity.

also this is a problem

Code VHDL - [expand]
1
If reset='0' and rising_edge(CLK) and exReady = '1' then


this is a gated clock and probably will throw and error in a synthesis tool. exReady should be in a if statement inside the rising_edge(CLK) if.
using an async reset the if structure should look something like this.

Code VHDL - [expand]
1
2
3
4
5
6
7
if reset = '1' then
  -- reset statements
elsif rising_edge(clk) then
  if exReady then
  -- your enabled code
  end if;
end if;



Regards
 


Sorry I think I posted the older code! lol I had already fixed that awhile back.

Thanks
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…