Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

different clock'event on the same file

Is it possible to write 2 processes, one activated by clock rise and the other by clock fall that could write the same register? I'm trying to construct a register file that may receive 2 sources of data. If they are for different register, it is ok, but for different data for the same register, I pretend to modify the same register on different clock edges. ¿Is it possible? What happens first? Rise edge or fall edge?

I get 2 errors:

Error: Can't resolve multiple constant drivers for net "register_array[0][31]" at regfile.vhd(109)

line 109 is in green color

Error: Constant driver at regfile.vhd(119)

line 119 is in brown color

Any suggestion?

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY regfile IS

PORT(

RegWrite_pipe0 : IN STD_LOGIC;

RegWrite_pipe1 : IN STD_LOGIC;

read_register_1_address_pipe0 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

read_register_2_address_pipe0 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

read_register_1_address_pipe1 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

read_register_2_address_pipe1 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

read_register_1_data_pipe0 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);

read_register_2_data_pipe0 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);

read_register_1_data_pipe1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);

read_register_2_data_pipe1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);

write_register_address_pipe0 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

write_register_data_pipe0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);

write_register_address_pipe1 : IN STD_LOGIC_VECTOR( 4 DOWNTO 0);

write_register_data_pipe1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);

clock : IN STD_LOGIC;

reset : IN STD_LOGIC

);

END regfile;

ARCHITECTURE behavior OF regfile IS

TYPE register_file IS ARRAY (0 TO 31) OF STD_LOGIC_VECTOR(31 DOWNTO 0);

SIGNAL register_array : register_file;

BEGIN

-- read registers 1 & 2 on rising edge of clock, i.e. they are registered

PROCESS

BEGIN

WAIT UNTIL clock'event and clock = '1';

read_register_1_data_pipe0 <= register_array(CONV_INTEGER(read_register_1_address_pipe0));

read_register_2_data_pipe0 <= register_array(CONV_INTEGER(read_register_2_address_pipe0));

read_register_1_data_pipe1 <= register_array(CONV_INTEGER(read_register_1_address_pipe1));

read_register_2_data_pipe1 <= register_array(CONV_INTEGER(read_register_2_address_pipe1));

END PROCESS;

PROCESS

BEGIN

WAIT UNTIL clock'event and clock = '1';

IF reset = '1' THEN

-- Initial register values on reset are ceros

-- use loop to automatically generate reset logic for all registers

FOR i IN 0 TO 31 LOOP

register_array(i) <= X"00000000";

END LOOP;

-- Write back to register - don't write to register 0

ELSIF (RegWrite_pipe0 = '1') AND (RegWrite_pipe1 = '0') AND (write_register_address_pipe0 /= 0) THEN

register_array(CONV_INTEGER(write_register_address_pipe0)) <= write_register_data_pipe0;

ELSIF (RegWrite_pipe0 = '0') AND (RegWrite_pipe1 = '1') AND (write_register_address_pipe1 /= 0) THEN

register_array(CONV_INTEGER(write_register_address_pipe1)) <= write_register_data_pipe1;

ELSIF (RegWrite_pipe0 = '1') AND (RegWrite_pipe1 = '1') AND (write_register_address_pipe0 /= 0) AND (write_register_address_pipe1 /= 0) THEN

IF (write_register_address_pipe0 /= write_register_address_pipe1) THEN

register_array(CONV_INTEGER(write_register_address_pipe0)) <= write_register_data_pipe0;

register_array(CONV_INTEGER(write_register_address_pipe1)) <= write_register_data_pipe1;

ELSE

register_array(CONV_INTEGER(write_register_address_pipe0)) <= write_register_data_pipe0;

-- para este caso el otro registro se escribe con el flanco de bajada del reloj

END IF;

END IF;

end process;

PROCESS

BEGIN

WAIT UNTIL clock'event and clock = '0';

IF (RegWrite_pipe0 = '1') AND (RegWrite_pipe0 = '1') AND (write_register_address_pipe0 /= 0) AND (write_register_address_pipe1 /= 0) THEN

IF (write_register_address_pipe0 = write_register_address_pipe1) THEN

register_array(CONV_INTEGER(write_register_address_pipe1)) <= write_register_data_pipe1;

END IF;

END IF;

end process;

END behavior;

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Don't think of VHDL, but the underlying hardware. There are no registers that are triggered of both edges(in any FPGAs), so whether VHDL could do it or not is irrelevant. You need two separate registers to clock the data, one rising and one falling, and then your own arbitration mux to determine which one is valid.