mirror of
https://github.com/Klagarge/Cursor.git
synced 2025-06-26 04:12:31 +00:00
Initial commit
This commit is contained in:
54
Libs/Memory/hdl/bramDualportWritefirst_bhv.vhd
Normal file
54
Libs/Memory/hdl/bramDualportWritefirst_bhv.vhd
Normal file
@ -0,0 +1,54 @@
|
||||
USE std.textio.all;
|
||||
|
||||
ARCHITECTURE bhv OF bramDualportWritefirst IS
|
||||
-- Define ramContent type
|
||||
type ramContentType is array(0 to (2**addressBitNb)-1) of bit_vector(dataBitNb-1 DOWNTO 0);
|
||||
|
||||
-- Define function to create initvalue signal
|
||||
impure function ReadRamContentFromFile(ramContentFilenAme : in string) return ramContentType is
|
||||
FILE ramContentFile : text is in ramContentFilenAme;
|
||||
variable ramContentFileLine : line;
|
||||
variable ramContent : ramContentType;
|
||||
begin
|
||||
for i in ramContentType'range loop
|
||||
readline(ramContentFile, ramContentFileLine);
|
||||
read(ramContentFileLine, ramContent(i));
|
||||
end loop;
|
||||
return ramContent;
|
||||
end function;
|
||||
|
||||
-- Declare ramContent signal
|
||||
shared variable ramContent: ramContentType := ReadRamContentFromFile(initFile);
|
||||
|
||||
BEGIN
|
||||
-- Port A
|
||||
process(clockA)
|
||||
begin
|
||||
if clockA'event and clockA='1' then
|
||||
if enA = '1' then
|
||||
if writeEnA = '1' then
|
||||
dataOutA <= dataInA;
|
||||
ramContent(to_integer(unsigned(addressA))) := to_bitvector(dataInA,'0');
|
||||
else
|
||||
dataOutA <= to_stdulogicvector(ramContent(to_integer(unsigned(addressA))));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Port B
|
||||
process(clockB)
|
||||
begin
|
||||
if clockB'event and clockB='1' then
|
||||
if enB = '1' then
|
||||
-- if writeEnB = '1' then
|
||||
-- ramContent(to_integer(unsigned(addressB))) := to_bitvector(dataInB,'0');
|
||||
-- dataOutB <= dataInB;
|
||||
-- else
|
||||
dataOutB <= to_stdulogicvector(ramContent(to_integer(unsigned(addressB))));
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE bhv;
|
39
Libs/Memory/hdl/bram_bhv.vhd
Normal file
39
Libs/Memory/hdl/bram_bhv.vhd
Normal file
@ -0,0 +1,39 @@
|
||||
USE std.textio.all;
|
||||
|
||||
ARCHITECTURE bhv OF bram IS
|
||||
-- Define ramContent type
|
||||
type ramContentType is array(0 to (2**addressBitNb)-1) of bit_vector(dataBitNb-1 DOWNTO 0);
|
||||
|
||||
-- Define function to create initvalue signal
|
||||
impure function ReadRamContentFromFile(ramContentFilenAme : in string) return ramContentType is
|
||||
FILE ramContentFile : text is in ramContentFilenAme;
|
||||
variable ramContentFileLine : line;
|
||||
variable ramContent : ramContentType;
|
||||
begin
|
||||
for i in ramContentType'range loop
|
||||
readline(ramContentFile, ramContentFileLine);
|
||||
read(ramContentFileLine, ramContent(i));
|
||||
end loop;
|
||||
return ramContent;
|
||||
end function;
|
||||
|
||||
-- Declare ramContent signal
|
||||
shared variable ramContent: ramContentType := ReadRamContentFromFile(initFile);
|
||||
|
||||
BEGIN
|
||||
-- Port A
|
||||
process(clock)
|
||||
begin
|
||||
if clock'event and clock='1' then
|
||||
if en = '1' then
|
||||
if writeEn = '1' then
|
||||
dataOut <= dataIn;
|
||||
ramContent(to_integer(unsigned(addressIn))) := to_bitvector(dataIn,'0');
|
||||
else
|
||||
dataOut <= to_stdulogicvector(ramContent(to_integer(unsigned(addressIn))));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE bhv;
|
55
Libs/Memory/hdl/bram_dualport_writefirst.vhd
Normal file
55
Libs/Memory/hdl/bram_dualport_writefirst.vhd
Normal file
@ -0,0 +1,55 @@
|
||||
USE std.textio.all;
|
||||
|
||||
ARCHITECTURE bhv OF bramContentDualportWritefirst IS
|
||||
-- Define ramContent type
|
||||
type ramContentType is array(0 to (2**addr_bit_nb)-1) of bit_vector(data_bit_nb-1 DOWNTO 0);
|
||||
|
||||
-- Define function to create initvalue signal
|
||||
impure function ReadRamContentFromFile(ramContentFilenAme : in string) return ramContentType is
|
||||
FILE ramContentFile : text is in ramContentFilenAme;
|
||||
variable ramContentFileLine : line;
|
||||
variable ramContent : ramContentType;
|
||||
begin
|
||||
for i in ramContentType'range loop
|
||||
readline(ramContentFile, ramContentFileLine);
|
||||
read(ramContentFileLine, ramContent(i));
|
||||
end loop;
|
||||
return ramContent;
|
||||
end function;
|
||||
|
||||
-- Declare ramContent signal
|
||||
shared variable ramContent: ramContentType := ReadRamContentFromFile(init_file);
|
||||
|
||||
BEGIN
|
||||
-- Port A
|
||||
process(clockA)
|
||||
begin
|
||||
if clockA'event and clockA='1' then
|
||||
if enA = '1' then
|
||||
if writeEnA = '1' then
|
||||
dataOutA <= dataInA;
|
||||
ramContent(to_integer(unsigned(addressA))) := to_bitvector(dataInA,'0');
|
||||
else
|
||||
dataOutA <= to_stdulogicvector(ramContent(to_integer(unsigned(addressA))));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Port B
|
||||
process(clockB)
|
||||
begin
|
||||
if clockB'event and clockB='1' then
|
||||
if enB = '1' then
|
||||
if writeEnB = '1' then
|
||||
ramContent(to_integer(unsigned(addressB))) := to_bitvector(dataInB,'0');
|
||||
dataOutB <= dataInB;
|
||||
else
|
||||
dataOutB <= to_stdulogicvector(ramContent(to_integer(unsigned(addressB))));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE bhv;
|
||||
|
@ -0,0 +1,73 @@
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- Copyright 2013 HES-SO Valais Wallis (www.hevs.ch)
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- FIFO bridge with bus width adaption
|
||||
-- A shift register that connects two FIFOs with different bus width.
|
||||
-- Many IP blocks nowadays have FIFO or FIFO-like interfaces and often they
|
||||
-- have to be connected. This block can the be used for this task, even if
|
||||
-- the bus size of the two FIFO interfaces is different.
|
||||
-- The Rx side bus width has to be a multiple of the Tx side bus width.
|
||||
--
|
||||
-- Created on 2013-10-18
|
||||
--
|
||||
-- Author: Oliver A. Gubler (oliver.gubler@hevs.ch)
|
||||
--
|
||||
-- 2014-10-06: *modify introduction text
|
||||
-- +add some comment
|
||||
-- *change readRx to a pulse
|
||||
-- *fix bug on shift of shiftreg_s
|
||||
-- 2013-10-18: +intital release
|
||||
-- ------------------------------------------------------------------------------
|
||||
--
|
||||
|
||||
library Common;
|
||||
use Common.CommonLib.all;
|
||||
|
||||
ARCHITECTURE behavioral OF fifoBridgeRxToTxBusWidthAdaptionRxBigger IS
|
||||
|
||||
signal cnt_s: unsigned(requiredBitNb(dataBitNbRx)-1 downto 0);
|
||||
signal shiftreg_s: std_ulogic_vector(dataBitNbRx-1 downto 0);
|
||||
signal emptyRx_s: std_ulogic; -- internal empty signal
|
||||
signal writeTx_s: std_ulogic; -- internal write signal
|
||||
|
||||
constant ratio_rxtx_c: positive range 1 to dataBitNbRx/dataBitNbTx:= dataBitNbRx/dataBitNbTx;
|
||||
|
||||
BEGIN
|
||||
|
||||
rx0: process(clock, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
shiftreg_s <= (others => '0');
|
||||
emptyRx_s <= '1';
|
||||
cnt_s <= (others => '0');
|
||||
writeTx_s <= '0';
|
||||
dataTx <= (others => '0');
|
||||
readRx <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
writeTx_s <= '0';
|
||||
readRx <= '0';
|
||||
-- fetch data
|
||||
if emptyRx_s = '1' and emptyRx = '0' then
|
||||
emptyRx_s <= '0';
|
||||
shiftreg_s <= dataRx;
|
||||
readRx <= '1';
|
||||
end if;
|
||||
-- shift data and put out
|
||||
-- after each write, wait one cylce to check if full gets high
|
||||
if emptyRx_s = '0' and fullTx = '0' and writeTx_s = '0' then
|
||||
shiftreg_s <= shiftreg_s(dataBitNbRx-dataBitNbTx-1 downto 0) & std_ulogic_vector(to_unsigned(0,dataBitNbTx));
|
||||
dataTx <= shiftreg_s(dataBitNbRx-1 downto dataBitNbRx-dataBitNbTx);
|
||||
writeTx_s <= '1';
|
||||
cnt_s <= cnt_s +1;
|
||||
if cnt_s >= ratio_rxtx_c-1 then
|
||||
cnt_s <= (others => '0');
|
||||
emptyRx_s <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
writeTx <= writeTx_s;
|
||||
|
||||
END ARCHITECTURE behavioral;
|
||||
|
@ -0,0 +1,75 @@
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- Copyright 2013 HES-SO Valais Wallis (www.hevs.ch)
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- FIFO bridge with bus width adaption
|
||||
-- A shift register that connects two FIFOs with different bus width.
|
||||
-- Many IP blocks nowadays have FIFO or FIFO-like interface. But the bus width
|
||||
-- varies often. This block can the be used to adapt the bus width to your own
|
||||
-- needs.
|
||||
-- The Tx side bus width has to be a multiple of the Rx side bus width.
|
||||
--
|
||||
-- Created on 2013-10-21
|
||||
--
|
||||
-- Version: 1.0
|
||||
-- Author: Oliver A. Gubler (oliver.gubler@hevs.ch)
|
||||
-- ------------------------------------------------------------------------------
|
||||
--
|
||||
|
||||
library common;
|
||||
use common.commonlib.all;
|
||||
|
||||
ARCHITECTURE behavioral OF fifoBridgeRxToTxBusWidthAdaptionTxbigger IS
|
||||
|
||||
constant ratio_txrx_c: positive range 1 to dataBitNbTx/dataBitNbRx:= dataBitNbTx/dataBitNbRx;
|
||||
|
||||
signal cnt_s: unsigned(requiredBitNb(ratio_txrx_c-1)-1 downto 0);
|
||||
signal shiftreg_s: std_ulogic_vector(dataBitNbTx-1 downto 0);
|
||||
signal fullTx_s: std_ulogic;
|
||||
signal emptyRx_s: std_ulogic;
|
||||
|
||||
BEGIN
|
||||
|
||||
rx0: process(clock, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
shiftreg_s <= (others => '0');
|
||||
readRx <= '1';
|
||||
emptyRx_s <= '1';
|
||||
cnt_s <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
readRx <= NOT fullTx_s;
|
||||
emptyRx_s <= '1';
|
||||
if emptyRx = '0' and fullTx_s = '0' then
|
||||
-- shiftreg_s(((to_integer(cnt_s)+1)*dataBitNbRx)-1 downto to_integer(cnt_s)*dataBitNbRx) <= dataRx;
|
||||
shiftreg_s <= shiftreg_s(dataBitNbTx-dataBitNbRx-1 downto 0) & dataRx;
|
||||
readRx <= '1';
|
||||
cnt_s <= cnt_s +1;
|
||||
if cnt_s >= ratio_txrx_c-1 then
|
||||
cnt_s <= (others => '0');
|
||||
emptyRx_s <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
tx0: process(clock, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
fullTx_s <= '1';
|
||||
writeTx <= '0';
|
||||
dataTx <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
fullTx_s <= fullTx;
|
||||
writeTx <= '0';
|
||||
-- no need to wait to check for full (in contrast to RxBigger)
|
||||
-- because it will forcibly take several clocks to fill the shiftreg
|
||||
if emptyRx_s = '0' and fullTx = '0' then
|
||||
dataTx <= shiftreg_s;
|
||||
writeTx <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE behavioral;
|
||||
|
||||
|
165
Libs/Memory/hdl/fifo_bram_rtl.vhd
Normal file
165
Libs/Memory/hdl/fifo_bram_rtl.vhd
Normal file
@ -0,0 +1,165 @@
|
||||
library Common;
|
||||
use Common.CommonLib.all;
|
||||
|
||||
architecture RTL of FIFO_bram is
|
||||
|
||||
subtype register_type is std_ulogic_vector(dataIn'high downto 0);
|
||||
type memory_type is array (0 to depth-1) of register_type;
|
||||
|
||||
signal writeCounter: unsigned(requiredBitNb(depth-1)-1 downto 0);
|
||||
signal readCounter: unsigned(writeCounter'range);
|
||||
signal memoryArray: memory_type;
|
||||
|
||||
type fifoStateType is (
|
||||
sEmpty, sFull,
|
||||
sRead, sWrite, sWriteFirst,
|
||||
sReadWrite, sWait
|
||||
);
|
||||
signal fifoState: fifoStateType;
|
||||
signal emptyCondition, fullCondition, empty_int: std_ulogic;
|
||||
|
||||
begin
|
||||
------------------------------------------------------------------------------
|
||||
-- read and write counters
|
||||
updateWriteCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
writeCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (write = '1') and (fullCondition = '0') then
|
||||
writeCounter <= writeCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateWriteCounter;
|
||||
|
||||
updateReadCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (read = '1') and (empty_int = '0') then
|
||||
readCounter <= readCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateReadCounter;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- memory access
|
||||
writeMem: process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if (write = '1') and (fullCondition = '0') then
|
||||
memoryArray(to_integer(writeCounter)) <= dataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process writeMem;
|
||||
|
||||
readMem: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
dataOut <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (read = '0') or (empty_int = '1') then
|
||||
dataOut <= memoryArray(to_integer(readCounter));
|
||||
else
|
||||
dataOut <= memoryArray(to_integer(readCounter+1));
|
||||
end if;
|
||||
end if;
|
||||
end process readMem;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- controls
|
||||
emptyCondition <= '1' when
|
||||
( (fifoState = sRead) and (writeCounter = readCounter) ) or
|
||||
(fifoState = sEmpty)
|
||||
else '0';
|
||||
|
||||
fullCondition <= '1' when
|
||||
( (fifoState = sWrite) and (writeCounter = readCounter) ) or
|
||||
(fifoState = sFull)
|
||||
else '0';
|
||||
|
||||
|
||||
fifoControl: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
fifoState <= sEmpty;
|
||||
elsif rising_edge(clock) then
|
||||
case fifoState is
|
||||
when sEmpty =>
|
||||
if write = '1' then
|
||||
fifoState <= sWriteFirst;
|
||||
end if;
|
||||
when sFull =>
|
||||
if (read = '1') then
|
||||
fifoState <= sRead;
|
||||
end if;
|
||||
when sRead =>
|
||||
if (read = '1') and (write = '1') then
|
||||
fifoState <= sReadWrite;
|
||||
elsif write = '1' then
|
||||
fifoState <= sWrite;
|
||||
elsif emptyCondition = '1' then
|
||||
fifoState <= sEmpty;
|
||||
elsif read = '1' then
|
||||
fifoState <= sRead;
|
||||
else
|
||||
fifoState <= sWait;
|
||||
end if;
|
||||
when sWriteFirst =>
|
||||
if (read = '1') and (write = '1') then
|
||||
fifoState <= sReadWrite;
|
||||
elsif write = '1' then
|
||||
fifoState <= sWrite;
|
||||
elsif read = '1' then
|
||||
fifoState <= sRead;
|
||||
else
|
||||
fifoState <= sWait;
|
||||
end if;
|
||||
when sWrite =>
|
||||
if (read = '1') and (write = '1') then
|
||||
fifoState <= sReadWrite;
|
||||
elsif read = '1' then
|
||||
fifoState <= sRead;
|
||||
elsif fullCondition = '1' then
|
||||
fifoState <= sFull;
|
||||
elsif write = '1' then
|
||||
fifoState <= sWrite;
|
||||
else
|
||||
fifoState <= sWait;
|
||||
end if;
|
||||
when sReadWrite =>
|
||||
if (read = '0') and (write = '0') then
|
||||
fifoState <= sWait;
|
||||
elsif (read = '1') and (write = '0') then
|
||||
fifoState <= sRead;
|
||||
elsif (write = '1') and (read = '0') then
|
||||
fifoState <= sWrite;
|
||||
end if;
|
||||
when sWait =>
|
||||
if (read = '1') and (write = '1') then
|
||||
fifoState <= sReadWrite;
|
||||
elsif read = '1' then
|
||||
fifoState <= sRead;
|
||||
elsif write = '1' then
|
||||
fifoState <= sWrite;
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end process fifoControl;
|
||||
|
||||
|
||||
full <= '1' when
|
||||
(fifoState = sFull) or
|
||||
(fullCondition = '1')
|
||||
else '0';
|
||||
|
||||
empty_int <= '1' when
|
||||
(fifoState = sEmpty) or
|
||||
(fifoState = sWriteFirst) or
|
||||
( (emptyCondition = '1') and (fifoState = sRead) )
|
||||
else '0';
|
||||
empty <= empty_int;
|
||||
|
||||
end RTL;
|
63
Libs/Memory/hdl/fifo_minimal.vhd
Normal file
63
Libs/Memory/hdl/fifo_minimal.vhd
Normal file
@ -0,0 +1,63 @@
|
||||
library Common;
|
||||
use Common.CommonLib.all;
|
||||
|
||||
architecture minimal of FIFO_bram is
|
||||
|
||||
subtype register_type is std_ulogic_vector(dataIn'high downto 0);
|
||||
type memory_type is array (0 to depth-1) of register_type;
|
||||
|
||||
signal writeCounter: unsigned(requiredBitNb(depth)-1 downto 0);
|
||||
signal readCounter: unsigned(writeCounter'range);
|
||||
signal memoryArray : memory_type;
|
||||
|
||||
begin
|
||||
|
||||
updateWriteCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
writeCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if write = '1' then
|
||||
writeCounter <= writeCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateWriteCounter;
|
||||
|
||||
updateReadCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if read = '1' then
|
||||
readCounter <= readCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateReadCounter;
|
||||
|
||||
writeMem: process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if write = '1' then
|
||||
memoryArray(to_integer(writeCounter)) <= dataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process writeMem;
|
||||
|
||||
dataOut <= memoryArray(to_integer(readCounter));
|
||||
|
||||
checkStatus: process(readCounter, writeCounter)
|
||||
begin
|
||||
if readCounter = writeCounter then
|
||||
empty <= '1';
|
||||
else
|
||||
empty <= '0';
|
||||
end if;
|
||||
if writeCounter+1 = readCounter then
|
||||
full <= '1';
|
||||
else
|
||||
full <= '0';
|
||||
end if;
|
||||
end process checkStatus;
|
||||
|
||||
end minimal;
|
||||
|
37
Libs/Memory/hdl/fifo_oneRegister_rtl.vhd
Normal file
37
Libs/Memory/hdl/fifo_oneRegister_rtl.vhd
Normal file
@ -0,0 +1,37 @@
|
||||
architecture oneRegister of FIFO_oneRegister is
|
||||
|
||||
signal dataRegister: std_ulogic_vector(dataIn'range);
|
||||
|
||||
begin
|
||||
|
||||
writeReg: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
dataRegister <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if write = '1' then
|
||||
dataRegister <= dataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process writeReg;
|
||||
|
||||
dataOut <= dataRegister;
|
||||
|
||||
manageFlags: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
empty <= '1';
|
||||
full <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if write = '1' then
|
||||
empty <= '0';
|
||||
full <= '1';
|
||||
elsif read = '1' then
|
||||
empty <= '1';
|
||||
full <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process manageFlags;
|
||||
|
||||
end oneRegister;
|
||||
|
118
Libs/Memory/hdl/fifo_pim.vhd
Normal file
118
Libs/Memory/hdl/fifo_pim.vhd
Normal file
@ -0,0 +1,118 @@
|
||||
library Common;
|
||||
use Common.CommonLib.all;
|
||||
|
||||
architecture pim of FIFO_bram is
|
||||
|
||||
type mem_t is array (depth-1 downto 0) of std_ulogic_vector(dataIn'range);
|
||||
subtype mem_range_r is natural range requiredBitNb(depth)-1 downto 0;
|
||||
subtype ptr_range_r is natural range requiredBitNb(depth)+1-1 downto 0;
|
||||
|
||||
signal mem : mem_t := (others => (others => '0'));
|
||||
|
||||
signal full_int : std_logic;
|
||||
signal empty_int : std_logic;
|
||||
signal write_error : std_logic;
|
||||
signal read_error : std_logic;
|
||||
signal read_ptr : unsigned(ptr_range_r);
|
||||
signal read_ptr_next : unsigned(ptr_range_r);
|
||||
signal write_ptr : unsigned(ptr_range_r);
|
||||
signal write_ptr_next : unsigned(ptr_range_r);
|
||||
|
||||
signal used_int : unsigned(ptr_range_r);
|
||||
|
||||
begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- Free / used
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
fifo_count_proc: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
used_int <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if write = '1' and full_int = '0' then
|
||||
used_int <= used_int + 1;
|
||||
end if;
|
||||
if read = '1' and empty_int = '0' then
|
||||
used_int <= used_int - 1;
|
||||
end if;
|
||||
|
||||
-- Simultaneous read/write -> no change
|
||||
-- ignore full_int, since it is valid
|
||||
if write = '1' and read = '1' and empty_int = '0' then
|
||||
used_int <= used_int;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- FIFO status
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
full_int <= '1' when (write_ptr(write_ptr'left) /= read_ptr(read_ptr'left))
|
||||
and ((write_ptr(mem_range_r) = read_ptr(mem_range_r)))
|
||||
else '0';
|
||||
empty_int <= '1' when (write_ptr = read_ptr) else '0';
|
||||
|
||||
full <= full_int;
|
||||
empty <= empty_int;
|
||||
|
||||
write_ptr_next <= write_ptr + 1;
|
||||
read_ptr_next <= read_ptr + 1;
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- FIFO pointers
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
fifo_ptr_proc: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
write_ptr <= (others => '0');
|
||||
read_ptr <= (others => '0');
|
||||
write_error <= '0';
|
||||
read_error <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
write_error <= '0';
|
||||
read_error <= '0';
|
||||
if write = '1' then
|
||||
if full_int = '0' or read = '1' then
|
||||
write_ptr <= write_ptr_next;
|
||||
else
|
||||
write_error <= '1';
|
||||
end if;
|
||||
end if;
|
||||
if read = '1' then
|
||||
if empty_int = '0' then
|
||||
read_ptr <= read_ptr_next;
|
||||
else
|
||||
read_error <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- FIFO RAM
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
fifo_out_proc : process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
dataOut <= mem(to_integer(read_ptr(mem_range_r)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fifo_in_proc : process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if write = '1' and full_int = '0' then
|
||||
mem(to_integer(write_ptr(mem_range_r))) <= dataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end pim;
|
||||
|
97
Libs/Memory/hdl/fifo_rtl_minimal.vhd
Normal file
97
Libs/Memory/hdl/fifo_rtl_minimal.vhd
Normal file
@ -0,0 +1,97 @@
|
||||
--
|
||||
-- VHDL Architecture Memory.fifo_minimal
|
||||
--
|
||||
-- Created:
|
||||
-- by - uadmin.UNKNOWN (WE3877)
|
||||
-- at - 13:54:33 11.07.2012
|
||||
--
|
||||
-- using Mentor Graphics HDL Designer(TM) 2009.2 (Build 10)
|
||||
--
|
||||
library Common;
|
||||
use Common.CommonLib.all;
|
||||
|
||||
architecture RTL_minimal of FIFO is
|
||||
|
||||
subtype register_type is std_ulogic_vector(dataIn'high downto 0);
|
||||
type memory_type is array (0 to depth-1) of register_type;
|
||||
|
||||
signal writeCounter: unsigned(requiredBitNb(depth)-1 downto 0);
|
||||
signal readCounter: unsigned(writeCounter'range);
|
||||
signal memoryArray : memory_type;
|
||||
|
||||
begin
|
||||
|
||||
updateWriteCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
writeCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if write = '1' then
|
||||
writeCounter <= writeCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateWriteCounter;
|
||||
|
||||
updateReadCounter: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if read = '1' then
|
||||
readCounter <= readCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateReadCounter;
|
||||
|
||||
writeMem: process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if write = '1' then
|
||||
memoryArray(to_integer(writeCounter)) <= dataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process writeMem;
|
||||
|
||||
dataOut <= memoryArray(to_integer(readCounter));
|
||||
|
||||
-- checkStatus: process(reset, clock)
|
||||
-- begin
|
||||
-- if reset = '1' then
|
||||
-- empty <= '1';
|
||||
-- full <= '0';
|
||||
-- elsif rising_edge(clock) then
|
||||
-- if readCounter+1 = writeCounter then
|
||||
-- if read = '1' then
|
||||
-- empty <= '1';
|
||||
-- end if;
|
||||
-- elsif writeCounter = readCounter then
|
||||
-- if write = '1' then
|
||||
-- empty <= '0';
|
||||
-- end if;
|
||||
-- if read = '1' then
|
||||
-- full <= '0';
|
||||
-- end if;
|
||||
-- elsif writeCounter+1 = readCounter then
|
||||
-- if write = '1' then
|
||||
-- full <= '1';
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end process checkStatus;
|
||||
|
||||
checkStatus: process(readCounter, writeCounter)
|
||||
begin
|
||||
if readCounter = writeCounter then
|
||||
empty <= '1';
|
||||
else
|
||||
empty <= '0';
|
||||
end if;
|
||||
if writeCounter+1 = readCounter then
|
||||
full <= '1';
|
||||
else
|
||||
full <= '0';
|
||||
end if;
|
||||
end process checkStatus;
|
||||
|
||||
END ARCHITECTURE RTL_minimal;
|
||||
|
84
Libs/Memory/hdl/fifobridgerxtotx_rtl.vhd
Normal file
84
Libs/Memory/hdl/fifobridgerxtotx_rtl.vhd
Normal file
@ -0,0 +1,84 @@
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- Copyright 2012 HES-SO Valais Wallis (www.hevs.ch)
|
||||
-- ------------------------------------------------------------------------------
|
||||
-- FIFO bridge with bus width adaptation
|
||||
-- A register that connects two FIFOs.
|
||||
-- Many IP blocks nowadays have FIFO or FIFO-like interfaces and often they
|
||||
-- have to be connected. This block can the be used for this task.
|
||||
--
|
||||
-- Created on 2012
|
||||
--
|
||||
-- Author: Oliver A. Gubler (oliver.gubler@hevs.ch)
|
||||
--
|
||||
-- 2016-04-01: fix bug in FWFT read when full
|
||||
-- 2016-03-22: +add FirstWordFallThrough (FWFT) generic
|
||||
-- 2012: +intital release
|
||||
-- ------------------------------------------------------------------------------
|
||||
--
|
||||
|
||||
ARCHITECTURE RTL OF fifoBridgeRxToTx IS
|
||||
|
||||
signal read1: std_ulogic;
|
||||
signal read2: std_ulogic;
|
||||
signal read: std_ulogic;
|
||||
signal storedData: std_ulogic_vector(data1'range);
|
||||
signal write: std_ulogic;
|
||||
|
||||
BEGIN
|
||||
|
||||
readControl: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
read1 <= '0';
|
||||
read2 <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if (empty1 = '0') and (full2 = '0') then
|
||||
read1 <= '1';
|
||||
else
|
||||
read1 <= '0';
|
||||
end if;
|
||||
read2 <= read1;
|
||||
end if;
|
||||
end process readControl;
|
||||
|
||||
read <= not empty1 and not full2 when firstWordFallThrough
|
||||
else not empty1 and read1;
|
||||
rd1 <= read;
|
||||
|
||||
readData: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
storedData <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if firstWordFallThrough then
|
||||
storedData <= data1;
|
||||
else
|
||||
if read = '1' then
|
||||
storedData <= data1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process readData;
|
||||
|
||||
data2 <= storedData;
|
||||
|
||||
writeControl: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
write <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if firstWordFallThrough then
|
||||
write <= not empty1 and not full2;
|
||||
else
|
||||
if read = '1' then
|
||||
write <= '1';
|
||||
else
|
||||
write <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process writeControl;
|
||||
|
||||
wr2 <= write;
|
||||
|
||||
end RTL;
|
140
Libs/Memory/hdl/flashController_RTL.vhd
Normal file
140
Libs/Memory/hdl/flashController_RTL.vhd
Normal file
@ -0,0 +1,140 @@
|
||||
ARCHITECTURE RTL OF flashController IS
|
||||
|
||||
signal addressReg: unsigned(flashAddr'range);
|
||||
signal dataOutReg: std_ulogic_vector(flashDataOut'range);
|
||||
signal dataInReg: std_ulogic_vector(flashDataIn'range);
|
||||
type sequenceStateType is (
|
||||
idle,
|
||||
waitForBus1, waitForBus0,
|
||||
startAccess, waitAcccessEnd
|
||||
);
|
||||
signal sequenceState: sequenceStateType;
|
||||
signal read: std_ulogic;
|
||||
signal startCounter: std_ulogic;
|
||||
signal sequenceCounter: unsigned(3 downto 0);
|
||||
signal endOfCount: std_ulogic;
|
||||
signal readDataValid: std_ulogic;
|
||||
signal flashCE: std_ulogic;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- memory reset
|
||||
memRst_n <= not '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- address
|
||||
storeAddress: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
addressReg <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (flashRd = '1') or (flashWr = '1') then
|
||||
addressReg <= shift_left(flashAddr, 1);
|
||||
end if;
|
||||
end if;
|
||||
end process storeAddress;
|
||||
|
||||
memAddress <= std_ulogic_vector(addressReg);
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- data out
|
||||
storeDataOut: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
dataOutReg <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if flashWr = '1' then
|
||||
dataOutReg <= flashDataOut;
|
||||
end if;
|
||||
end if;
|
||||
end process storeDataOut;
|
||||
|
||||
memDataOut <= flashDataOut;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- data in
|
||||
readDataValid <= '1' when (read = '1') and (endOfCount = '1') else '0';
|
||||
|
||||
storeDataIn: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
dataInReg <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if readDataValid = '1' then
|
||||
dataInReg <= memDataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process storeDataIn;
|
||||
|
||||
flashDataIn <= dataInReg when readDataValid = '0' else memDataIn;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read/write sequence
|
||||
busAccessFsm: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
read <= '0';
|
||||
sequenceState <= idle;
|
||||
elsif rising_edge(clock) then
|
||||
case sequenceState is
|
||||
when idle =>
|
||||
if flashRd = '1' then
|
||||
read <= '1';
|
||||
sequenceState <= waitForBus1;
|
||||
elsif flashWr = '1' then
|
||||
read <= '0';
|
||||
sequenceState <= waitForBus1;
|
||||
end if;
|
||||
when waitForBus1 =>
|
||||
if memBusEn_n = '1' then
|
||||
sequenceState <= waitForBus0;
|
||||
end if;
|
||||
when waitForBus0 =>
|
||||
if memBusEn_n = '0' then
|
||||
sequenceState <= startAccess;
|
||||
end if;
|
||||
when startAccess =>
|
||||
sequenceState <= waitAcccessEnd;
|
||||
when waitAcccessEnd =>
|
||||
if endOfCount = '1' then
|
||||
sequenceState <= idle;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end process busAccessFsm;
|
||||
|
||||
|
||||
startCounter <= '1' when sequenceState = startAccess else '0';
|
||||
endOfCount <= '1'
|
||||
when ( (sequenceCounter = rdWaitState) and (read = '1') ) or
|
||||
( (sequenceCounter = wrWaitState) and (read = '0') )
|
||||
else '0';
|
||||
|
||||
countSequence: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
sequenceCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if sequenceCounter = 0 then
|
||||
if startCounter = '1' then
|
||||
sequenceCounter <= sequenceCounter + 1;
|
||||
end if;
|
||||
else
|
||||
if endOfCount = '1' then
|
||||
sequenceCounter <= (others => '0');
|
||||
else
|
||||
sequenceCounter <= sequenceCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process countSequence;
|
||||
|
||||
flashCE <= '0' when sequenceCounter = 0 else '1';
|
||||
flashCE_n <= not flashCE;
|
||||
memWR_n <= not '1' when (read = '0') and (flashCE = '1') and (endOfCount = '0')
|
||||
else not '0';
|
||||
memOE_n <= not '1' when (read = '1') and (flashCE = '1') else not '0';
|
||||
|
||||
flashDataValid <= endOfCount;
|
||||
|
||||
END ARCHITECTURE RTL;
|
36
Libs/Memory/hdl/sdramControllerBuildAddress_RTL.vhd
Normal file
36
Libs/Memory/hdl/sdramControllerBuildAddress_RTL.vhd
Normal file
@ -0,0 +1,36 @@
|
||||
ARCHITECTURE RTL OF sdramControllerBuildAddress IS
|
||||
|
||||
constant addressPrecharge: std_ulogic_vector(memAddress'range)
|
||||
:= (10=> '1', others => '-');
|
||||
constant addressModeRegU : unsigned(memAddress'range)
|
||||
:= resize("0" & "00" & "010" & "0" & "000", memAddress'length);
|
||||
-- ll,10 = reserved,
|
||||
-- 9 = '0' programmed burst length => burst length applicable for both rd and wr
|
||||
-- 8,7 = Op mode = 00 => standard operation (all other states are reserved)
|
||||
-- 6,5,4 = CAS latency = 010 => cas latency of 2
|
||||
-- 3 = Burst Type = '0' => Sequential (not interleaved)
|
||||
-- 2,1,0 = Brust Length = 000 => brust length is 1
|
||||
constant addressModeReg : std_ulogic_vector(memAddress'range)
|
||||
:= std_ulogic_vector(addressModeRegU);
|
||||
|
||||
BEGIN
|
||||
|
||||
buildAddresses: process(ramAddr, addrSelPrecharge, addrSelModeReg, addrSelRow, addrSelCol)
|
||||
begin
|
||||
memBankAddress <= std_ulogic_vector(ramAddr(ramAddr'high downto ramAddr'high-memBankAddress'length+1));
|
||||
if addrSelPrecharge = '1' then
|
||||
memAddress <= addressPrecharge;
|
||||
elsif addrSelModeReg = '1' then
|
||||
memAddress <= addressModeReg;
|
||||
elsif addrSelRow = '1' then
|
||||
memAddress <= std_ulogic_vector(ramAddr(rowAddressBitNb+colAddressBitNb-1 downto colAddressBitNb));
|
||||
elsif addrSelCol = '1' then
|
||||
memAddress(memAddress'high downto colAddressBitNb) <= (others => '0');
|
||||
memAddress(10) <= '1';
|
||||
memAddress(colAddressBitNb-1 downto 0) <= std_ulogic_vector(ramAddr(colAddressBitNb-1 downto 0));
|
||||
else
|
||||
memAddress <= (others => '-');
|
||||
end if;
|
||||
end process buildAddresses;
|
||||
|
||||
END ARCHITECTURE RTL;
|
48
Libs/Memory/hdl/sdramControllerRefreshCounter_RTL.vhd
Normal file
48
Libs/Memory/hdl/sdramControllerRefreshCounter_RTL.vhd
Normal file
@ -0,0 +1,48 @@
|
||||
ARCHITECTURE RTL OF sdramControllerRefreshCounter IS
|
||||
|
||||
signal delayCounter: unsigned(delayCounterBitNb-1 downto 0);
|
||||
signal endOfDelay: std_ulogic;
|
||||
|
||||
BEGIN
|
||||
|
||||
countDelay : process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
delayCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if endOfDelay = '1' then
|
||||
delayCounter <= to_unsigned(1, delayCounter'length);
|
||||
else
|
||||
delayCounter <= delayCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process countDelay;
|
||||
|
||||
findEndOfDelay: process(powerUpDone, delayCounter)
|
||||
begin
|
||||
endOfDelay <= '0';
|
||||
if powerUpDone = '0' then
|
||||
if delayCounter+1 = 0 then
|
||||
endOfDelay <= '1';
|
||||
end if;
|
||||
else
|
||||
if delayCounter+1 >= refreshPeriodNb then
|
||||
endOfDelay <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process findEndOfDelay;
|
||||
|
||||
endOfRefreshCount <= endOfDelay;
|
||||
|
||||
signalRefresh: process(powerUpDone, delayCounter)
|
||||
begin
|
||||
selectRefresh <= '0';
|
||||
if (powerUpDone = '1') and (delayCounter < 1024) then
|
||||
if (delayCounter <= 16) or (delayCounter(3 downto 0) = 0) then
|
||||
selectRefresh <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process signalRefresh;
|
||||
|
||||
|
||||
END ARCHITECTURE RTL;
|
18
Libs/Memory/hdl/sdramControllerSR_RTL.vhd
Normal file
18
Libs/Memory/hdl/sdramControllerSR_RTL.vhd
Normal file
@ -0,0 +1,18 @@
|
||||
ARCHITECTURE RTL OF sdramControllerSR IS
|
||||
BEGIN
|
||||
|
||||
setReset: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
flag <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if setFlag = '1' then
|
||||
flag <= '1';
|
||||
elsif resetFlag = '1' then
|
||||
flag <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process setReset;
|
||||
|
||||
END ARCHITECTURE RTL;
|
||||
|
17
Libs/Memory/hdl/sdramControllerSampleDataIn_RTL.vhd
Normal file
17
Libs/Memory/hdl/sdramControllerSampleDataIn_RTL.vhd
Normal file
@ -0,0 +1,17 @@
|
||||
ARCHITECTURE RTL OF sdramControllerSampleDataIn IS
|
||||
BEGIN
|
||||
|
||||
sampleRamData: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
ramDataIn <= (others => '0');
|
||||
elsif falling_edge(clock) then
|
||||
if sampleData = '1' then
|
||||
ramDataIn <= memDataIn;
|
||||
end if;
|
||||
end if;
|
||||
end process sampleRamData;
|
||||
|
||||
|
||||
END ARCHITECTURE RTL;
|
||||
|
14
Libs/Memory/hdl/sdramControllerStoreData_RTL.vhd
Normal file
14
Libs/Memory/hdl/sdramControllerStoreData_RTL.vhd
Normal file
@ -0,0 +1,14 @@
|
||||
ARCHITECTURE RTL OF sdramControllerStoreData IS
|
||||
BEGIN
|
||||
|
||||
storeData : process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
memDataOut <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
memDataOut <= ramDataOut;
|
||||
end if;
|
||||
end process storeData;
|
||||
|
||||
END ARCHITECTURE RTL;
|
||||
|
24
Libs/Memory/hdl/sdramControllerTimingsShiftRegister_RTL.vhd
Normal file
24
Libs/Memory/hdl/sdramControllerTimingsShiftRegister_RTL.vhd
Normal file
@ -0,0 +1,24 @@
|
||||
ARCHITECTURE RTL OF sdramControllerTimingsShiftRegister IS
|
||||
|
||||
--constant leadingZeroesNb: positive := 2;
|
||||
--constant leadingZeroes: std_ulogic_vector(1 to leadingZeroesNb) := (others => '0');
|
||||
--signal shiftReg: std_ulogic_vector(1 to timerDone'high-leadingZeroesNb);
|
||||
signal shiftReg: std_ulogic_vector(1 to timerDone'high);
|
||||
|
||||
BEGIN
|
||||
|
||||
shiftToken : process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
shiftReg <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
shiftReg(1) <= timerStart;
|
||||
shiftReg(2 to shiftReg'right) <= shiftReg(1 to shiftReg'right-1);
|
||||
end if;
|
||||
end process shiftToken;
|
||||
|
||||
--timerDone <= leadingZeroes & shiftReg;
|
||||
timerDone <= shiftReg;
|
||||
|
||||
END ARCHITECTURE RTL;
|
||||
|
Reference in New Issue
Block a user