VHDL综合:连接到以下多个驱动程序

时间:2013-12-04 22:22:22

标签: vhdl xilinx synthesis

我为预订站写了这段代码:

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;

但是当我运行综合时会产生这个错误:

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:
似乎无法看到多个驱动程序在哪里。

我正在使用xilinx进行合成

该项目的想法是设计一个2个宽的超标量与乱序执行 我完成了所有单元,现在我正在进行顶级设计,我刚开始使用xilinx。

我之前使用的是更简单的项目。

任何想法?

1 个答案:

答案 0 :(得分:0)

CAM1CAM2块正在推动RS(0)RS(7)。事实上,它们看起来完全相同。他们应该连续运作吗?如果是这样,您需要定义一个中间信号作为CAM1的输出和CAM2的输入。