I wrote this code for a reservation station:
Library ieee;
use ieee.std_logic_1164.all;
entity RS_unit is
port(clk: in std_logic;
reset: in std_logic;
wr_enable1: in std_logic;
instr1: in std_logic_vector(15 downto 0);
instr1_tag: in std_logic_vector( 4 downto 0);
I1_opr1: in std_logic_vector(15 downto 0);
I1_valid1: in std_logic;
I1_opr2: in std_logic_vector(15 downto 0);
I1_valid2: in std_logic;
wr_enable2: in std_logic;
instr2: in std_logic_vector(15 downto 0);
instr2_tag: in std_logic_vector( 4 downto 0);
I2_opr1: in std_logic_vector(15 downto 0);
I2_valid1: in std_logic;
I2_opr2: in std_logic_vector(15 downto 0);
I2_valid2: in std_logic;
full: out std_logic;
wb_tag1: in std_logic_vector( 4 downto 0);
wb_data1: in std_logic_vector(15 downto 0);
wb_tag2: in std_logic_vector( 4 downto 0);
wb_data2: in std_logic_vector(15 downto 0);
disp1_opcode: out std_logic_vector(3 downto 0);
disp1_info: out std_logic_vector(3 downto 0);
disp1_opr1: out std_logic_vector(15 downto 0);
disp1_opr2: out std_logic_vector(15 downto 0);
disp1_tag: out std_logic_vector( 4 downto 0);
disp2_opcode: out std_logic_vector(3 downto 0);
disp2_info: out std_logic_vector(3 downto 0);
disp2_opr1: out std_logic_vector(15 downto 0);
disp2_opr2: out std_logic_vector(15 downto 0);
disp2_tag: out std_logic_vector( 4 downto 0));
end RS_unit;
architecture RS_arch of RS_unit is
type reservation_entry is record
free: std_logic;
tag: std_logic_vector( 4 downto 0);
op_code: std_logic_vector(3 downto 0);
op_info: std_logic_vector(3 downto 0);
opr1: std_logic_vector(15 downto 0);
valid1: std_logic;
opr2: std_logic_vector(15 downto 0);
valid2: std_logic;
end record;
type reservation_array is array(0 to 7) of reservation_entry;
signal RS: reservation_array;
signal I1_index: integer:=0;
signal I2_index: integer:=0;
signal disp1_index: integer:=0;
signal disp2_index: integer:=0;
begin
--priority selector
--to select first free entry
I1_index<=0 when RS(0).free='1' else
1 when RS(1).free='1' else
2 when RS(2).free='1' else
3 when RS(3).free='1' else
4 when RS(4).free='1' else
5 when RS(5).free='1' else
6 when RS(6).free='1' else
7 when RS(7).free='1' else
8;
--added the I1_index condition to avoid conflicts
I2_index<=0 when RS(0).free='1' and not(I1_index=0) else
1 when RS(1).free='1' and not(I1_index=1) else
2 when RS(2).free='1' and not(I1_index=2) else
3 when RS(3).free='1' and not(I1_index=3) else
4 when RS(4).free='1' and not(I1_index=4) else
5 when RS(5).free='1' and not(I1_index=5) else
6 when RS(6).free='1' and not(I1_index=6) else
7 when RS(7).free='1' and not(I1_index=7) else
8;
--used to search dispachable entries
--use same method as above
disp1_index<=0 when RS(0).valid1='1' and RS(0).valid2='1' and RS(0).free='0' else
1 when RS(1).valid1='1' and RS(1).valid2='1' and RS(1).free='0' else
2 when RS(2).valid1='1' and RS(2).valid2='1' and RS(2).free='0' else
3 when RS(3).valid1='1' and RS(3).valid2='1' and RS(3).free='0' else
4 when RS(4).valid1='1' and RS(4).valid2='1' and RS(4).free='0' else
5 when RS(5).valid1='1' and RS(5).valid2='1' and RS(5).free='0' else
6 when RS(6).valid1='1' and RS(6).valid2='1' and RS(6).free='0' else
7 when RS(7).valid1='1' and RS(7).valid2='1' and RS(7).free='0' else
8;
disp2_index<=0 when RS(0).valid1='1' and RS(0).valid2='1' and RS(0).free='0' and disp1_index/=0 else
1 when RS(1).valid1='1' and RS(1).valid2='1' and RS(1).free='0' and disp1_index/=1 else
2 when RS(2).valid1='1' and RS(2).valid2='1' and RS(2).free='0' and disp1_index/=2 else
3 when RS(3).valid1='1' and RS(3).valid2='1' and RS(3).free='0' and disp1_index/=3 else
4 when RS(4).valid1='1' and RS(4).valid2='1' and RS(4).free='0' and disp1_index/=4 else
5 when RS(5).valid1='1' and RS(5).valid2='1' and RS(5).free='0' and disp1_index/=5 else
6 when RS(6).valid1='1' and RS(6).valid2='1' and RS(6).free='0' and disp1_index/=6 else
7 when RS(7).valid1='1' and RS(7).valid2='1' and RS(7).free='0' and disp1_index/=7 else
8;
--CAM on 2 WB ports
--check both operands for each input tag
--if data is not valid and tags match
--replace with proper data and set valid bit
CAM1: for i in 0 to 7 generate
RS(i).valid1<='1' when (RS(i).valid1='0' and RS(i).opr1(4 downto 0)=wb_tag1) else RS(i).valid1;
RS(i).opr1<=wb_data1 when (RS(i).valid1='0' and RS(i).opr1(4 downto 0)=wb_tag1) else RS(i).opr1;
RS(i).valid2<='1' when (RS(i).valid2='0' and RS(i).opr2(4 downto 0)=wb_tag1) else RS(i).valid2;
RS(i).opr2<=wb_data1 when (RS(i).valid2='0' and RS(i).opr2(4 downto 0)=wb_tag1) else RS(i).opr2;
end generate;
CAM2: for j in 0 to 7 generate
RS(j).valid1<='1' when (RS(j).valid1='0' and RS(j).opr1(4 downto 0)=wb_tag2) else RS(j).valid1;
RS(j).opr1<=wb_data1 when (RS(j).valid1='0' and RS(j).opr1(4 downto 0)=wb_tag2) else RS(j).opr1;
RS(j).valid2<='1' when (RS(j).valid2='0' and RS(j).opr2(4 downto 0)=wb_tag2) else RS(j).valid2;
RS(j).opr2<=wb_data1 when (RS(j).valid2='0' and RS(j).opr2(4 downto 0)=wb_tag2) else RS(j).opr2;
end generate;
--set the full bit directly if any of the two intructions does not find a place
--this is when we stall at the decode stage
--whe the reservation station is full
full<='1' when(I1_index=8 or I2_index=8) else '0';
pipe: process
begin
wait until clk'event and clk='1';
if(reset='1') then
for i in 0 to 7 loop
RS(i).free<='1';
end loop;
else
--write the instruction in the proper entry in the RS
if(wr_enable1='1' and not(I1_index=8) ) then
RS(I1_index).free<='0';
RS(I1_index).tag<=instr1_tag;
RS(I1_index).op_code<=instr1(15 downto 12);
RS(I1_index).op_info<=instr1(3 downto 0);
RS(I1_index).opr1<=I1_opr1;
RS(I1_index).valid1<=I1_valid1;
RS(I1_index).opr2<=I1_opr2;
RS(I1_index).valid2<=I1_valid2;
end if;
if(wr_enable2='1' and not(I2_index=8)) then
RS(I2_index).free<='0';
RS(I2_index).tag<=instr2_tag;
RS(I2_index).op_code<=instr2(15 downto 12);
RS(I2_index).op_info<=instr2(3 downto 0);
RS(I2_index).opr1<=I2_opr1;
RS(I2_index).valid1<=I2_valid1;
RS(I2_index).opr2<=I2_opr2;
RS(I2_index).valid2<=I2_valid2;
end if;
--This is a 2 wide superscalar hence we need to sipatch 2 instructions
--dispatch 1
if(disp1_index/=8) then
disp1_opcode<=RS(disp1_index).op_code;
disp1_info<=RS(disp1_index).op_info;
disp1_opr1<=RS(disp1_index).opr1;
disp1_opr2<=RS(disp1_index).opr2;
disp1_tag<=RS(disp1_index).tag;
RS(disp1_index).free<='1';
end if;
--dispatch 2
if(disp2_index/=8) then
disp2_opcode<=RS(disp2_index).op_code;
disp2_info<=RS(disp2_index).op_info;
disp2_opr1<=RS(disp2_index).opr1;
disp2_opr2<=RS(disp2_index).opr2;
disp2_tag<=RS(disp2_index).tag;
RS(disp2_index).free<='1';
end if;
end if;
end process;
end RS_arch;
but when i run synthesis it generates this error:
ERROR:HDLCompiler:1401 - "D:\the wisso files\AUB\EECE 421\Fall 2013-2014\CPU_SYNTH\rs.vhd" Line 72: Signal RS[0]_opr1[15] in unit RS_unit is connected to following multiple drivers:
cant seem to see where are the multiple drivers.
I am using xilinx for synthesis
the Idea of the project is to design a 2 wide superscalar with out of order execution I finished all of the units now i am working on the top level design and I just started using xilinx with it.
I used before but on much simpler projects.
any ideas?
The
CAM1
andCAM2
blocks are both drivingRS(0)
throughRS(7)
. In fact, they appear identical. Are they supposed to operate serially? If so, you need to define an intermediate signal to use as the output ofCAM1
and the input ofCAM2
.