Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17246 Discussions

different clock'event on the same file

Altera_Forum
Honored Contributor II
1,139 Views

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;
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
439 Views

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.

0 Kudos
Reply