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;
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!!!
if (Reset /= '0') then
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.
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
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.
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.
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;
Code VHDL - [expand] 1 if (Reset = '0' and CLK'event and CLK='1') then
Code VHDL - [expand] 1 If reset='0' and clk='1' then
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;
i assume its due to incorrect sensitivity lists.
This is still code that will not compile for real hardware.
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
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?