Question

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?

Was it helpful?

Solution

The CAM1 and CAM2 blocks are both driving RS(0) through RS(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 of CAM1 and the input of CAM2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top