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
CAM1andCAM2blocks 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 ofCAM1and the input ofCAM2.