141 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| --==============================================================================
 | |
| --
 | |
| -- AHB general purpose input/outputs
 | |
| --
 | |
| -- Provides "ioNb" input/output signals .
 | |
| --
 | |
| --------------------------------------------------------------------------------
 | |
| --
 | |
| -- Write registers
 | |
| --
 | |
| -- 00, data register receives the values to drive the output lines.
 | |
| -- 01, output enable register defines the signal direction:
 | |
| --     when '1', the direction is "out".
 | |
| --
 | |
| --------------------------------------------------------------------------------
 | |
| --
 | |
| -- Read registers
 | |
| -- 00, data register provides the values detected on the lines.
 | |
| --
 | |
| ARCHITECTURE studentVersion OF ahbGpio IS
 | |
| 
 | |
| signal addresses: unsigned(hAddr'range);
 | |
| signal bRead: std_ulogic;
 | |
| signal bWrite: std_ulogic;
 | |
| signal bDone: std_ulogic;
 | |
| 
 | |
| 
 | |
| BEGIN
 | |
| 
 | |
|   process(hReset_n, hClk) begin
 | |
|     if hReset_n = '0' then
 | |
|       -- AHB-Lite
 | |
|       --hRData  <=  (OTHERS => 'Z');
 | |
|       hRData  <=  (OTHERS => '0');
 | |
|       hReady  <=  '1';  
 | |
|       hResp   <=  '0';  
 | |
| 
 | |
|       -- Out
 | |
|       ioOut <= (OTHERS => '0');
 | |
|       ioEn  <= (OTHERS => '0');
 | |
| 
 | |
|       addresses  <=  (OTHERS => '0');
 | |
|       bRead <= '0';
 | |
|       bWrite <= '0';
 | |
|       bDone <= '0';
 | |
|     elsif rising_edge(hClk) then
 | |
|       if hSel = '1' then
 | |
|         bWrite <= hWrite;
 | |
|         bRead <= not hWrite;
 | |
|         addresses <= hAddr;
 | |
|         hReady <= '0';
 | |
|         bDone <= '0';
 | |
|       else
 | |
|         bWrite <= '0';
 | |
|         bRead <= '0';
 | |
|       end if;
 | |
| 
 | |
|       if bRead = '1' and bWrite = '0' then
 | |
|         -------------------------------------------------------------------------
 | |
|         -- READ
 | |
|         -------------------------------------------------------------------------
 | |
|         
 | |
|         if addresses = "00" then
 | |
|           -- ##### Read data register #####
 | |
|           --hRData <= unsigned(resize(ioIn, ioNb));
 | |
|           for i in 0 to ioNb-1 loop
 | |
|             hRData(i) <= ioIn(i);
 | |
|           end loop;
 | |
|           bDone <= '1';
 | |
| 
 | |
|         elsif addresses = "01" then
 | |
|           report "@@@@@@@@@@ Not possible to change output in READ mode @@@@@@@@@@" severity error;
 | |
| 
 | |
|         end if;
 | |
| 
 | |
|       elsif bRead = '0' and bWrite = '1' then
 | |
|         -------------------------------------------------------------------------
 | |
|         -- WRITE
 | |
|         -------------------------------------------------------------------------
 | |
|         
 | |
|         if addresses = "00" then
 | |
|           -- ##### Write data register #####
 | |
|           --ioOut <= resize(std_ulogic_vector(hWData), ioNb);
 | |
|           for i in 0 to ioNb-1 loop
 | |
|             ioOut(i) <= hWData(i);
 | |
|           end loop;
 | |
|           bDone <= '1';
 | |
| 
 | |
|         elsif addresses = "01" then
 | |
|           -- ##### Write direction register #####
 | |
|           --ioEn <= hWData;
 | |
|           for i in 0 to ioNb-1 loop
 | |
|             ioEn(i) <= hWData(i);
 | |
|           end loop;
 | |
|           bDone <= '1';
 | |
|           
 | |
|         end if;
 | |
| 
 | |
|       elsif bRead = '1' and bWrite = '1' then
 | |
|         -------------------------------------------------------------------------
 | |
|         -- SHOULD NEVER HAPPEN
 | |
|         -------------------------------------------------------------------------
 | |
|         report "@@@@@@@@@@ READ and WRITE can't happened in same time @@@@@@@@@@" severity error;
 | |
| 
 | |
|       end if;
 | |
| 
 | |
|       if (ioIn and ioEn) = (ioEn and ioOut) then
 | |
|         hResp <= '0';
 | |
|       else
 | |
|         hResp <= '1';
 | |
|       end if;
 | |
| 
 | |
|       if bDone = '1' then
 | |
|         --hRData  <=  (OTHERS => 'Z');
 | |
|         bDone <= '0';
 | |
|         hReady <= '1';
 | |
|       end if;
 | |
| 
 | |
|     end if;
 | |
| 
 | |
|     for i in (ioNb-1) downto 0 loop
 | |
|       if (ioEn(i) and ioIn(i)) /= (ioEn(i) and ioOut(i)) then
 | |
|         --ioEn(i) <= '0';
 | |
|         report "an output was in conflict" severity note;
 | |
|       end if;
 | |
|     end loop;
 | |
| 
 | |
|   end process;
 | |
| 
 | |
|   -- AHB-Lite
 | |
| --  hRData  <=	(OTHERS => '0');
 | |
| --  hReady  <=	'0';	
 | |
| --  hResp	  <=	'0';	
 | |
| 
 | |
|   -- Out
 | |
| --  ioOut <= (OTHERS => '0');
 | |
| --  ioEn  <= (OTHERS => '0');
 | |
| 
 | |
| END ARCHITECTURE studentVersion;
 | |
| 
 |