Hi all,
I am working on creating a simple computer in VHDL. Right now, I am trying to add a multiplication instruction but it is giving me problems. The code compiles fine. However, when I simulate the program, it shows the "MULTOUT" signal as being unknown (X) and it never takes on the correct value. Everything else if fine except for the multiplication part. The code is given below. Any advice would be much appreciated.
LIBRARY IEEE;
LIBRARY ALTERA_MF;
LIBRARY LPM;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
USE ieee.numeric_std.ALL;
USE ALTERA_MF.ALTERA_MF_COMPONENTS.ALL;
USE LPM.LPM_COMPONENTS.ALL;
ENTITY SCOMP IS
PORT(
CLOCK : IN STD_LOGIC;
RESETN : IN STD_LOGIC;
PC_OUT : OUT STD_LOGIC_VECTOR( 9 DOWNTO 0);
AC_OUT : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
MDR_OUT : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
MAR_OUT : OUT STD_LOGIC_VECTOR( 9 DOWNTO 0);
IO_WRITE : OUT STD_LOGIC;
IO_CYCLE : OUT STD_LOGIC;
IO_ADDR : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0);
IO_DATA : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END SCOMP;
ARCHITECTURE a OF SCOMP IS
TYPE STATE_TYPE IS (
RESET_PC,
FETCH,
DECODE,
EX_LOAD,
EX_STORE,
EX_STORE2,
EX_ADD,
EX_SUB,
EX_JUMP,
EX_JNEG,
EX_JPOS,
EX_JZERO,
EX_AND,
EX_OR,
EX_XOR,
EX_SHIFT,
EX_ADDI,
EX_ILOAD,
EX_ISTORE,
EX_CALL,
EX_RETURN,
EX_IN,
EX_OUT,
EX_OUT2,
EX_MULT
);
TYPE STACK_TYPE IS ARRAY (0 TO 7) OF STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL STATE : STATE_TYPE;
SIGNAL PC_STACK : STACK_TYPE;
SIGNAL IO_IN : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL AC : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL AC_SHIFTED : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL IR : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL MDR : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL PC : STD_LOGIC_VECTOR( 9 DOWNTO 0);
SIGNAL MEM_ADDR : STD_LOGIC_VECTOR( 9 DOWNTO 0);
SIGNAL MW : STD_LOGIC;
SIGNAL IO_WRITE_INT : STD_LOGIC;
SIGNAL MULTOUT : STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
PC_OUT <= PC;
AC_OUT <= AC;
MDR_OUT <= MDR;
MAR_OUT <= IR(9 DOWNTO 0);
IO_WRITE <= IO_WRITE_INT;
IO_ADDR <= IR(7 DOWNTO 0);
WITH STATE SELECT
MEM_ADDR <= PC WHEN FETCH,
IR(9 DOWNTO 0) WHEN OTHERS;
WITH STATE SELECT
IO_CYCLE <= '1' WHEN EX_IN,
'1' WHEN EX_OUT2,
'0' WHEN OTHERS;
PROCESS (CLOCK, RESETN)
BEGIN
IF (RESETN = '0') THEN -- Active low, asynchronous reset
STATE <= RESET_PC;
ELSIF (RISING_EDGE(CLOCK)) THEN
CASE STATE IS
WHEN RESET_PC =>
MW <= '0'; -- Clear memory write flag
PC <= "0000000000"; -- Reset PC to the beginning of memory, address 0x000
AC <= x"0000"; -- Clear AC register
STATE <= FETCH;
WHEN FETCH =>
MW <= '0'; -- Clear memory write flag
IO_WRITE_INT <= '0';
IR <= MDR; -- Latch instruction into the IR
PC <= PC + 1; -- Increment PC to next instruction address
STATE <= DECODE;
WHEN DECODE =>
CASE IR(15 downto 10) IS
WHEN "000000" => -- No Operation (NOP)
STATE <= FETCH;
WHEN "000001" => -- LOAD
STATE <= EX_LOAD;
WHEN "000010" => -- STORE
STATE <= EX_STORE;
WHEN "000011" => -- ADD
STATE <= EX_ADD;
WHEN "000100" => -- SUB
STATE <= EX_SUB;
WHEN "000101" => -- JUMP
STATE <= EX_JUMP;
WHEN "000110" => -- JNEG
STATE <= EX_JNEG;
WHEN "000111" => -- JPOS
STATE <= EX_JPOS;
WHEN "001000" => -- JZERO
STATE <= EX_JZERO;
WHEN "001001" => -- AND
STATE <= EX_AND;
WHEN "001010" => -- OR
STATE <= EX_OR;
WHEN "001011" => -- XOR
STATE <= EX_XOR;
WHEN "001100" => -- SHIFT
STATE <= EX_SHIFT;
WHEN "001101" => -- ADDI
STATE <= EX_ADDI;
WHEN "001110" => -- ILOAD
STATE <= EX_ILOAD;
WHEN "001111" => -- ISTORE
STATE <= EX_ISTORE;
WHEN "010000" => -- CALL
STATE <= EX_CALL;
WHEN "010001" => -- RETURN
STATE <= EX_RETURN;
WHEN "010010" => -- IN
STATE <= EX_IN;
WHEN "010011" => -- OUT
IO_WRITE_INT <= '1';
STATE <= EX_OUT;
WHEN "010100" =>
STATE <= EX_MULT; -- MULT
WHEN OTHERS =>
STATE <= FETCH; -- Invalid opcodes default to NOP
END CASE;
WHEN EX_LOAD =>
AC <= MDR; -- Latch data from MDR (memory contents) to AC
STATE <= FETCH;
WHEN EX_STORE =>
MW <= '1'; -- Raise MW to write AC to MEM
STATE <= EX_STORE2;
WHEN EX_STORE2 =>
MW <= '0'; -- Drop MW to end write cycle
STATE <= FETCH;
WHEN EX_ADD =>
AC <= AC + MDR;
STATE <= FETCH;
WHEN EX_SUB =>
AC <= AC - MDR;
STATE <= FETCH;
WHEN EX_JUMP =>
PC <= IR(9 DOWNTO 0);
STATE <= FETCH;
WHEN EX_JNEG =>
IF (AC(15) = '1') THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_JPOS =>
IF ((AC(15) = '0') AND (AC /= x"0000")) THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_JZERO =>
IF (AC = x"0000") THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_AND =>
AC <= AC AND MDR;
STATE <= FETCH;
WHEN EX_OR =>
AC <= AC OR MDR;
STATE <= FETCH;
WHEN EX_XOR =>
AC <= AC XOR MDR;
STATE <= FETCH;
WHEN EX_SHIFT =>
AC <= AC_SHIFTED;
STATE <= FETCH;
WHEN EX_ADDI =>
AC <= AC + (IR(9) & IR(9) & IR(9) & IR(9) &
IR(9) & IR(9) & IR(9 DOWNTO 0));
STATE <= FETCH;
WHEN EX_ILOAD =>
IR(9 DOWNTO 0) <= MDR(9 DOWNTO 0);
STATE <= EX_LOAD;
WHEN EX_ISTORE =>
IR(9 DOWNTO 0) <= MDR(9 DOWNTO 0);
STATE <= EX_STORE;
WHEN EX_CALL =>
FOR i IN 0 TO 6 LOOP
PC_STACK(i + 1) <= PC_STACK(i);
END LOOP;
PC_STACK(0) <= PC;
PC <= IR(9 DOWNTO 0);
STATE <= FETCH;
WHEN EX_RETURN =>
FOR i IN 0 TO 6 LOOP
PC_STACK(i) <= PC_STACK(i + 1);
END LOOP;
PC <= PC_STACK(0);
STATE <= FETCH;
WHEN EX_IN =>
AC <= IO_DATA;
STATE <= FETCH;
WHEN EX_OUT =>
STATE <= EX_OUT2;
WHEN EX_OUT2 =>
STATE <= FETCH;
WHEN EX_MULT =>
MULTOUT <= AC*MDR;
AC <= MULTOUT(23 DOWNTO 8 );
STATE <= FETCH;
WHEN OTHERS =>
STATE <= FETCH; -- If an invalid state is reached, return to FETCH
END CASE;
END IF;
END PROCESS;
END a;
I am working on creating a simple computer in VHDL. Right now, I am trying to add a multiplication instruction but it is giving me problems. The code compiles fine. However, when I simulate the program, it shows the "MULTOUT" signal as being unknown (X) and it never takes on the correct value. Everything else if fine except for the multiplication part. The code is given below. Any advice would be much appreciated.
LIBRARY IEEE;
LIBRARY ALTERA_MF;
LIBRARY LPM;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
USE ieee.numeric_std.ALL;
USE ALTERA_MF.ALTERA_MF_COMPONENTS.ALL;
USE LPM.LPM_COMPONENTS.ALL;
ENTITY SCOMP IS
PORT(
CLOCK : IN STD_LOGIC;
RESETN : IN STD_LOGIC;
PC_OUT : OUT STD_LOGIC_VECTOR( 9 DOWNTO 0);
AC_OUT : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
MDR_OUT : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
MAR_OUT : OUT STD_LOGIC_VECTOR( 9 DOWNTO 0);
IO_WRITE : OUT STD_LOGIC;
IO_CYCLE : OUT STD_LOGIC;
IO_ADDR : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0);
IO_DATA : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END SCOMP;
ARCHITECTURE a OF SCOMP IS
TYPE STATE_TYPE IS (
RESET_PC,
FETCH,
DECODE,
EX_LOAD,
EX_STORE,
EX_STORE2,
EX_ADD,
EX_SUB,
EX_JUMP,
EX_JNEG,
EX_JPOS,
EX_JZERO,
EX_AND,
EX_OR,
EX_XOR,
EX_SHIFT,
EX_ADDI,
EX_ILOAD,
EX_ISTORE,
EX_CALL,
EX_RETURN,
EX_IN,
EX_OUT,
EX_OUT2,
EX_MULT
);
TYPE STACK_TYPE IS ARRAY (0 TO 7) OF STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL STATE : STATE_TYPE;
SIGNAL PC_STACK : STACK_TYPE;
SIGNAL IO_IN : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL AC : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL AC_SHIFTED : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL IR : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL MDR : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL PC : STD_LOGIC_VECTOR( 9 DOWNTO 0);
SIGNAL MEM_ADDR : STD_LOGIC_VECTOR( 9 DOWNTO 0);
SIGNAL MW : STD_LOGIC;
SIGNAL IO_WRITE_INT : STD_LOGIC;
SIGNAL MULTOUT : STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
PC_OUT <= PC;
AC_OUT <= AC;
MDR_OUT <= MDR;
MAR_OUT <= IR(9 DOWNTO 0);
IO_WRITE <= IO_WRITE_INT;
IO_ADDR <= IR(7 DOWNTO 0);
WITH STATE SELECT
MEM_ADDR <= PC WHEN FETCH,
IR(9 DOWNTO 0) WHEN OTHERS;
WITH STATE SELECT
IO_CYCLE <= '1' WHEN EX_IN,
'1' WHEN EX_OUT2,
'0' WHEN OTHERS;
PROCESS (CLOCK, RESETN)
BEGIN
IF (RESETN = '0') THEN -- Active low, asynchronous reset
STATE <= RESET_PC;
ELSIF (RISING_EDGE(CLOCK)) THEN
CASE STATE IS
WHEN RESET_PC =>
MW <= '0'; -- Clear memory write flag
PC <= "0000000000"; -- Reset PC to the beginning of memory, address 0x000
AC <= x"0000"; -- Clear AC register
STATE <= FETCH;
WHEN FETCH =>
MW <= '0'; -- Clear memory write flag
IO_WRITE_INT <= '0';
IR <= MDR; -- Latch instruction into the IR
PC <= PC + 1; -- Increment PC to next instruction address
STATE <= DECODE;
WHEN DECODE =>
CASE IR(15 downto 10) IS
WHEN "000000" => -- No Operation (NOP)
STATE <= FETCH;
WHEN "000001" => -- LOAD
STATE <= EX_LOAD;
WHEN "000010" => -- STORE
STATE <= EX_STORE;
WHEN "000011" => -- ADD
STATE <= EX_ADD;
WHEN "000100" => -- SUB
STATE <= EX_SUB;
WHEN "000101" => -- JUMP
STATE <= EX_JUMP;
WHEN "000110" => -- JNEG
STATE <= EX_JNEG;
WHEN "000111" => -- JPOS
STATE <= EX_JPOS;
WHEN "001000" => -- JZERO
STATE <= EX_JZERO;
WHEN "001001" => -- AND
STATE <= EX_AND;
WHEN "001010" => -- OR
STATE <= EX_OR;
WHEN "001011" => -- XOR
STATE <= EX_XOR;
WHEN "001100" => -- SHIFT
STATE <= EX_SHIFT;
WHEN "001101" => -- ADDI
STATE <= EX_ADDI;
WHEN "001110" => -- ILOAD
STATE <= EX_ILOAD;
WHEN "001111" => -- ISTORE
STATE <= EX_ISTORE;
WHEN "010000" => -- CALL
STATE <= EX_CALL;
WHEN "010001" => -- RETURN
STATE <= EX_RETURN;
WHEN "010010" => -- IN
STATE <= EX_IN;
WHEN "010011" => -- OUT
IO_WRITE_INT <= '1';
STATE <= EX_OUT;
WHEN "010100" =>
STATE <= EX_MULT; -- MULT
WHEN OTHERS =>
STATE <= FETCH; -- Invalid opcodes default to NOP
END CASE;
WHEN EX_LOAD =>
AC <= MDR; -- Latch data from MDR (memory contents) to AC
STATE <= FETCH;
WHEN EX_STORE =>
MW <= '1'; -- Raise MW to write AC to MEM
STATE <= EX_STORE2;
WHEN EX_STORE2 =>
MW <= '0'; -- Drop MW to end write cycle
STATE <= FETCH;
WHEN EX_ADD =>
AC <= AC + MDR;
STATE <= FETCH;
WHEN EX_SUB =>
AC <= AC - MDR;
STATE <= FETCH;
WHEN EX_JUMP =>
PC <= IR(9 DOWNTO 0);
STATE <= FETCH;
WHEN EX_JNEG =>
IF (AC(15) = '1') THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_JPOS =>
IF ((AC(15) = '0') AND (AC /= x"0000")) THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_JZERO =>
IF (AC = x"0000") THEN
PC <= IR(9 DOWNTO 0);
END IF;
STATE <= FETCH;
WHEN EX_AND =>
AC <= AC AND MDR;
STATE <= FETCH;
WHEN EX_OR =>
AC <= AC OR MDR;
STATE <= FETCH;
WHEN EX_XOR =>
AC <= AC XOR MDR;
STATE <= FETCH;
WHEN EX_SHIFT =>
AC <= AC_SHIFTED;
STATE <= FETCH;
WHEN EX_ADDI =>
AC <= AC + (IR(9) & IR(9) & IR(9) & IR(9) &
IR(9) & IR(9) & IR(9 DOWNTO 0));
STATE <= FETCH;
WHEN EX_ILOAD =>
IR(9 DOWNTO 0) <= MDR(9 DOWNTO 0);
STATE <= EX_LOAD;
WHEN EX_ISTORE =>
IR(9 DOWNTO 0) <= MDR(9 DOWNTO 0);
STATE <= EX_STORE;
WHEN EX_CALL =>
FOR i IN 0 TO 6 LOOP
PC_STACK(i + 1) <= PC_STACK(i);
END LOOP;
PC_STACK(0) <= PC;
PC <= IR(9 DOWNTO 0);
STATE <= FETCH;
WHEN EX_RETURN =>
FOR i IN 0 TO 6 LOOP
PC_STACK(i) <= PC_STACK(i + 1);
END LOOP;
PC <= PC_STACK(0);
STATE <= FETCH;
WHEN EX_IN =>
AC <= IO_DATA;
STATE <= FETCH;
WHEN EX_OUT =>
STATE <= EX_OUT2;
WHEN EX_OUT2 =>
STATE <= FETCH;
WHEN EX_MULT =>
MULTOUT <= AC*MDR;
AC <= MULTOUT(23 DOWNTO 8 );
STATE <= FETCH;
WHEN OTHERS =>
STATE <= FETCH; -- If an invalid state is reached, return to FETCH
END CASE;
END IF;
END PROCESS;
END a;