mirror of
https://github.com/Lemonochrme/vhdl_processor.git
synced 2025-06-08 17:00:50 +02:00
Fixed timing problems by re-organizing the pipeline
This commit is contained in:
parent
f180a80f12
commit
909de11c18
6 changed files with 96 additions and 147 deletions
|
@ -60,7 +60,7 @@
|
||||||
<Option Name="EnableBDX" Val="FALSE"/>
|
<Option Name="EnableBDX" Val="FALSE"/>
|
||||||
<Option Name="DSABoardId" Val="basys3"/>
|
<Option Name="DSABoardId" Val="basys3"/>
|
||||||
<Option Name="FeatureSet" Val="FeatureSet_Classic"/>
|
<Option Name="FeatureSet" Val="FeatureSet_Classic"/>
|
||||||
<Option Name="WTXSimLaunchSim" Val="306"/>
|
<Option Name="WTXSimLaunchSim" Val="501"/>
|
||||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||||
|
|
125
src/cpu.vhd
125
src/cpu.vhd
|
@ -60,49 +60,54 @@ ARCHITECTURE cpu_arch OF cpu IS
|
||||||
-- Signaux internes
|
-- Signaux internes
|
||||||
signal PC : STD_LOGIC_VECTOR (7 downto 0) := "00000000"; -- Program Counter
|
signal PC : STD_LOGIC_VECTOR (7 downto 0) := "00000000"; -- Program Counter
|
||||||
signal IR : STD_LOGIC_VECTOR (31 downto 0); -- Instruction Register
|
signal IR : STD_LOGIC_VECTOR (31 downto 0); -- Instruction Register
|
||||||
signal OP : STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
signal A : STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
signal B : STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
signal C : STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
|
|
||||||
signal OP_DI : STD_LOGIC_VECTOR (7 downto 0);
|
signal OP_LI_DI : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal A_DI : STD_LOGIC_VECTOR (7 downto 0);
|
signal A_LI_DI : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal B_DI : STD_LOGIC_VECTOR (7 downto 0);
|
signal B_LI_DI : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal C_DI : STD_LOGIC_VECTOR (7 downto 0);
|
signal C_LI_DI : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
|
||||||
signal OP_EX : STD_LOGIC_VECTOR (7 downto 0);
|
signal OP_DI_EX : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal A_EX : STD_LOGIC_VECTOR (7 downto 0);
|
signal A_DI_EX : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal B_EX : STD_LOGIC_VECTOR (7 downto 0);
|
signal B_DI_EX : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal C_EX : STD_LOGIC_VECTOR (7 downto 0);
|
signal C_DI_EX : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
|
||||||
signal OP_MEM: STD_LOGIC_VECTOR (7 downto 0);
|
signal OP_EX_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal A_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
signal A_EX_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal B_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
signal B_EX_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal C_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
signal C_EX_MEM : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
|
||||||
signal OP_RE : STD_LOGIC_VECTOR (7 downto 0);
|
signal OP_MEM_RE: STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal A_RE : STD_LOGIC_VECTOR (7 downto 0);
|
signal A_MEM_RE : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal B_RE : STD_LOGIC_VECTOR (7 downto 0);
|
signal B_MEM_RE : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
signal C_RE : STD_LOGIC_VECTOR (7 downto 0);
|
signal C_MEM_RE : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Register file specific signals
|
||||||
|
signal R_ADDRESS_A_HANDLE : STD_LOGIC_VECTOR(3 DOWNTO 0);
|
||||||
|
signal R_ADDRESS_B_HANDLE : STD_LOGIC_VECTOR(3 DOWNTO 0);
|
||||||
signal W_ADDRESS_HANDLE : STD_LOGIC_VECTOR(3 DOWNTO 0);
|
signal W_ADDRESS_HANDLE : STD_LOGIC_VECTOR(3 DOWNTO 0);
|
||||||
signal W_DATA_HANDLE : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
signal W_DATA_HANDLE : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
signal W_ENABLE_HANDLE : STD_LOGIC;
|
signal W_ENABLE_HANDLE : STD_LOGIC;
|
||||||
|
signal A_DATA_OUT_HANDLE : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
signal B_DATA_OUT_HANDLE : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Instantiation des composants
|
-- Instantiation des composants
|
||||||
RegisterFile_Instance: reg PORT MAP (
|
RegisterFile_Instance: reg PORT MAP (
|
||||||
address_A => "0000",
|
address_A => R_ADDRESS_A_HANDLE,
|
||||||
address_B => "0000",
|
address_B => R_ADDRESS_B_HANDLE,
|
||||||
address_W => W_ADDRESS_HANDLE,
|
address_W => W_ADDRESS_HANDLE,
|
||||||
W_Enable => W_ENABLE_HANDLE,
|
W_Enable => W_ENABLE_HANDLE,
|
||||||
W_Data => W_DATA_HANDLE,
|
W_Data => W_DATA_HANDLE,
|
||||||
reset => '1',
|
reset => '1', -- Reset unactive
|
||||||
clk => clk,
|
clk => clk,
|
||||||
A_Data => open,
|
A_Data => A_DATA_OUT_HANDLE,
|
||||||
B_Data => open
|
B_Data => B_DATA_OUT_HANDLE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
InstructionMemory_Instance: instruction PORT MAP (
|
InstructionMemory_Instance: instruction PORT MAP (
|
||||||
instruction => PC,
|
instruction => PC,
|
||||||
code => IR,
|
code => IR,
|
||||||
|
@ -110,83 +115,69 @@ BEGIN
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Pipeline
|
-- Pipeline
|
||||||
|
OP_LI_DI <= IR(31 downto 24);
|
||||||
-- Lecture Instruction (LI)
|
A_LI_DI <= IR(23 downto 16);
|
||||||
LI: process(clk)
|
B_LI_DI <= IR(15 downto 8);
|
||||||
begin
|
C_LI_DI <= IR(7 downto 0);
|
||||||
if rising_edge(clk) then
|
LI_DI: process(clk)
|
||||||
-- Charger les instruction
|
|
||||||
OP <= IR(31 downto 24);
|
|
||||||
A <= IR(23 downto 16);
|
|
||||||
B <= IR(15 downto 8);
|
|
||||||
C <= IR(7 downto 0);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
DI: process(clk)
|
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
-- Banc de registre
|
-- Banc de registre
|
||||||
OP_DI <= OP;
|
case OP_LI_DI is
|
||||||
case OP is
|
when X"06" => -- AFC
|
||||||
when X"06" =>
|
OP_DI_EX <= OP_LI_DI;
|
||||||
A_DI <= A;
|
A_DI_EX <= A_LI_DI;
|
||||||
B_DI <= B;
|
B_DI_EX <= B_LI_DI;
|
||||||
C_DI <= C;
|
C_DI_EX <= C_LI_DI;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
EX: process(clk)
|
DI_EX: process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
-- Executer instruction si nécéssaire (ALU)
|
-- Executer instruction si nécéssaire (ALU)
|
||||||
OP_EX <= OP_DI;
|
case OP_DI_EX is
|
||||||
case OP_DI is
|
|
||||||
when X"06" =>
|
when X"06" =>
|
||||||
A_EX <= A_DI;
|
OP_EX_MEM <= OP_DI_EX;
|
||||||
B_EX <= B_DI;
|
A_EX_MEM <= A_DI_EX;
|
||||||
C_EX <= C_DI;
|
B_EX_MEM <= B_DI_EX;
|
||||||
|
C_EX_MEM <= C_DI_EX;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MEM: process(clk)
|
EX_MEM: process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
-- Ecrire ou lire memoire des données
|
-- Ecrire ou lire memoire des données
|
||||||
OP_MEM <= OP_EX;
|
case OP_EX_MEM is
|
||||||
case OP_EX is
|
|
||||||
when X"06" =>
|
when X"06" =>
|
||||||
A_MEM <= A_EX;
|
OP_MEM_RE <= OP_EX_MEM;
|
||||||
B_MEM <= B_EX;
|
A_MEM_RE <= A_EX_MEM;
|
||||||
C_MEM <= C_EX;
|
B_MEM_RE <= B_EX_MEM;
|
||||||
|
C_MEM_RE <= C_EX_MEM;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
RE: process(clk)
|
-- Write Back (RE)
|
||||||
|
MEM_RE: process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
-- Ecrire dans les registres
|
-- Ecrire dans les registres
|
||||||
OP_RE <= OP_MEM;
|
case OP_MEM_RE is -- Si OP_RE : b c Si OP_MEM : a b
|
||||||
case OP_MEM is
|
|
||||||
when X"06" =>
|
when X"06" =>
|
||||||
A_RE <= A_MEM;
|
|
||||||
B_RE <= B_MEM;
|
|
||||||
C_RE <= C_MEM;
|
|
||||||
|
|
||||||
W_ENABLE_HANDLE <= '1';
|
W_ENABLE_HANDLE <= '1';
|
||||||
W_ADDRESS_HANDLE <= A_RE(3 downto 0);
|
W_ADDRESS_HANDLE <= A_MEM_RE(3 downto 0);
|
||||||
W_DATA_HANDLE <= B_RE;
|
W_DATA_HANDLE <= B_MEM_RE;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
|
|
|
@ -16,7 +16,7 @@ architecture Behavioral of data_memory is
|
||||||
type MemoryArray is array (0 to 255) of STD_LOGIC_VECTOR(7 downto 0);
|
type MemoryArray is array (0 to 255) of STD_LOGIC_VECTOR(7 downto 0);
|
||||||
signal Memory : MemoryArray := (others => X"00");
|
signal Memory : MemoryArray := (others => X"00");
|
||||||
begin
|
begin
|
||||||
process(CLK, RST)
|
process(CLK)
|
||||||
begin
|
begin
|
||||||
if RST = '1' then
|
if RST = '1' then
|
||||||
Memory <= (others => X"00"); -- Reset the memory to 0x00
|
Memory <= (others => X"00"); -- Reset the memory to 0x00
|
||||||
|
|
|
@ -25,10 +25,10 @@ entity instruction is
|
||||||
end loop;
|
end loop;
|
||||||
init_result(0) := X"06000A0F";
|
init_result(0) := X"06000A0F";
|
||||||
init_result(1) := X"06010B0F";
|
init_result(1) := X"06010B0F";
|
||||||
init_result(2) := X"06020C0F";
|
init_result(2) := X"06020B0F";
|
||||||
init_result(3) := X"06030D0F";
|
|
||||||
init_result(4) := X"06040E0F";
|
|
||||||
init_result(5) := X"06050F0F";
|
-- init_result(6) := X"0502010F";
|
||||||
return init_result;
|
return init_result;
|
||||||
end function init;
|
end function init;
|
||||||
end instruction;
|
end instruction;
|
||||||
|
@ -37,9 +37,9 @@ architecture behavior_instr of instruction is
|
||||||
-- Memory variable
|
-- Memory variable
|
||||||
signal code_memory: code_array := init;
|
signal code_memory: code_array := init;
|
||||||
begin
|
begin
|
||||||
process(instruction, clk) is
|
process(clk) is
|
||||||
begin
|
begin
|
||||||
if clk'event AND clk = '1' then
|
if rising_edge(clk) then
|
||||||
code <= code_memory(CONV_INTEGER(UNSIGNED(instruction)));
|
code <= code_memory(CONV_INTEGER(UNSIGNED(instruction)));
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
|
||||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
||||||
|
|
||||||
entity pipeline_step is
|
|
||||||
port(
|
|
||||||
A_in: in STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
B_in: in STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
C_in: in STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
OP_in: in STD_LOGIC_VECTOR(3 downto 0);
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
A_out: out STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
B_out: out STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
C_out: out STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
OP_out: out STD_LOGIC_VECTOR(3 downto 0)
|
|
||||||
);
|
|
||||||
end pipeline_step;
|
|
||||||
|
|
||||||
architecture behavior_pipeline_step of pipeline_step is
|
|
||||||
begin
|
|
||||||
process(clk, A_in, B_in, C_in, OP_in)
|
|
||||||
begin
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
A_out <= A_in;
|
|
||||||
B_out <= B_in;
|
|
||||||
C_out <= C_in;
|
|
||||||
OP_out <= OP_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end behavior_pipeline_step;
|
|
|
@ -1,7 +1,6 @@
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
use IEEE.NUMERIC_STD.ALL;
|
||||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
||||||
|
|
||||||
entity reg is
|
entity reg is
|
||||||
port(
|
port(
|
||||||
|
@ -18,34 +17,24 @@ port(
|
||||||
end reg;
|
end reg;
|
||||||
|
|
||||||
architecture behavior_reg of reg is
|
architecture behavior_reg of reg is
|
||||||
-- Array of STD_LOGIC_VECTOR
|
type memory_array is array(0 to 15) of STD_LOGIC_VECTOR(7 downto 0);
|
||||||
type memory_array is array(0 to 15) of
|
|
||||||
STD_LOGIC_VECTOR(7 downto 0);
|
|
||||||
-- Memory variable
|
|
||||||
signal memory: memory_array;
|
signal memory: memory_array;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
-- Convert address_A and address_B to integers
|
-- bypass
|
||||||
-- Using Bypass to avoid delay between Read Data and Write Data if they are at the same time called (WEnable = 1)
|
A_Data <= memory(to_integer(unsigned(address_A))) when (W_Enable = '0' or address_A /= address_W)
|
||||||
A_Data <= memory(CONV_INTEGER(unsigned(address_A))) when (W_Enable = '0' or address_A /= address_W)
|
|
||||||
else W_Data;
|
else W_Data;
|
||||||
|
|
||||||
B_Data <= memory(CONV_INTEGER(unsigned(address_B))) when (W_Enable = '0' or address_B /= address_W)
|
B_Data <= memory(to_integer(unsigned(address_B))) when (W_Enable = '0' or address_B /= address_W)
|
||||||
else W_Data;
|
else W_Data;
|
||||||
|
|
||||||
-- Write data synchronously
|
process(clk)
|
||||||
process(address_W, W_Enable, W_Data, reset, clk) is
|
|
||||||
begin
|
begin
|
||||||
-- Reset the memory if shutdown
|
if rising_edge(clk) then
|
||||||
if reset = '0' then
|
if reset = '0' then
|
||||||
memory <= (others => "00000000");
|
memory <= (others => (others => '0'));
|
||||||
end if;
|
elsif W_Enable = '1' then
|
||||||
-- Else Doing writing routine at each clock tick
|
memory(to_integer(unsigned(address_W))) <= W_Data;
|
||||||
if reset = '1' then
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
if W_Enable = '1' then
|
|
||||||
memory(CONV_INTEGER(unsigned(address_W))) <= W_Data;
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
Loading…
Add table
Reference in a new issue