URL
https://opencores.org/ocsvn/copyblaze/copyblaze/trunk
Subversion Repositories copyblaze
Compare Revisions
- This comparison shows the changes necessary to convert path
/copyblaze/trunk/copyblaze/rtl/vhdl
- from Rev 57 to Rev 59
- ↔ Reverse comparison
Rev 57 → Rev 59
/soc/cp_copyBlaze_ecoSystem.vhd
0,0 → 1,277
-------------------------------------------------------------------------------- |
-- Company: |
-- |
-- File: cp_copyBlaze_ecoSystem.vhd |
-- |
-- Description: |
-- projet copyblaze |
-- copyBlaze processor + ROM => system |
-- |
-- File history: |
-- v1.0: 11/10/11: Creation |
-- |
-- Targeted device: ProAsic A3P250 VQFP100 |
-- Author: AbdAllah Meziti |
-------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.Usefull_Pkg.all; -- Usefull Package |
|
-------------------------------------------------------------------------------- |
-- Entity: cp_copyBlaze_ecoSystem |
-- |
-- Description: |
-- |
-- REMARQUE: |
-- |
-- |
-- History: |
-- 11/10/11 AM: Creation |
-- --------------------- |
-- xx/xx/xx AM: |
-- |
-------------------------------------------------------------------------------- |
entity cp_copyBlaze_ecoSystem is |
generic |
( |
GEN_WIDTH_DATA : positive := 8; |
GEN_WIDTH_PC : positive := 10; |
GEN_WIDTH_INST : positive := 18; |
|
GEN_DEPTH_STACK : positive := 15; -- Taille (en octet) de la Stack |
GEN_DEPTH_BANC : positive := 16; -- Taille (en octet) du Banc Register |
GEN_DEPTH_SCRATCH : positive := 64; -- Taille (en octet) du Scratch Pad |
|
GEN_INT_VECTOR : std_ulogic_vector(11 downto 0) := x"3FF" |
); |
Port ( |
-------------------------------------------------------------------------------- |
-- Signaux Systeme |
-------------------------------------------------------------------------------- |
Clk_i : in std_ulogic; |
--Rst_i_n : in std_ulogic; |
|
-------------------------------------------------------------------------------- |
-- Signaux Fonctionels |
-------------------------------------------------------------------------------- |
Interrupt_i : in std_ulogic; |
Interrupt_Ack_o : out std_ulogic; |
|
IN_PORT_i : in std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
OUT_PORT_o : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
PORT_ID_o : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
READ_STROBE_o : out std_ulogic; |
WRITE_STROBE_o : out std_ulogic; |
-------------------------------------------------------------------------------- |
-- Signaux WishBone |
-------------------------------------------------------------------------------- |
Freeze_i : in std_ulogic; |
|
-------------------------------------------------------------------------------- |
-- Signaux Wishbone Interface |
-------------------------------------------------------------------------------- |
-- RST_I : in std_ulogic; |
-- CLK_I : in std_ulogic; |
|
ADR_O : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
DAT_I : in std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
DAT_O : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
WE_O : out std_ulogic; |
SEL_O : out std_ulogic_vector(1 downto 0); |
|
STB_O : out std_ulogic; |
ACK_I : in std_ulogic; |
CYC_O : out std_ulogic |
); |
end cp_copyBlaze_ecoSystem; |
|
-------------------------------------------------------------------------------- |
-- Architecture: RTL |
-- of entity : cp_copyBlaze_ecoSystem |
-------------------------------------------------------------------------------- |
architecture rtl of cp_copyBlaze_ecoSystem is |
|
-------------------------------------------------------------------------------- |
|
-------------------------------------------------------------------------------- |
constant RESET_LENGTH : positive := 7; |
|
-------------------------------------------------------------------------------- |
|
-------------------------------------------------------------------------------- |
component cp_copyBlaze |
generic |
( |
GEN_WIDTH_DATA : positive := 8; |
GEN_WIDTH_PC : positive := 10; |
GEN_WIDTH_INST : positive := 18; |
|
GEN_DEPTH_STACK : positive := 15; -- Taille (en octet) de la Stack |
GEN_DEPTH_BANC : positive := 16; -- Taille (en octet) du Banc Register |
GEN_DEPTH_SCRATCH : positive := 64; -- Taille (en octet) du Scratch Pad |
|
GEN_INT_VECTOR : std_ulogic_vector(11 downto 0) := x"3FF" -- Interrupt Vector |
); |
port ( |
-------------------------------------------------------------------------------- |
-- Signaux Systeme |
-------------------------------------------------------------------------------- |
|
|
|
-------------------------------------------------------------------------------- |
-- Signaux Fonctionels |
-------------------------------------------------------------------------------- |
Address_o : out std_ulogic_vector(GEN_WIDTH_PC-1 downto 0); |
Instruction_i : in std_ulogic_vector(GEN_WIDTH_INST-1 downto 0); |
|
Interrupt_i : in std_ulogic; -- |
Interrupt_Ack_o : out std_ulogic; -- |
|
IN_PORT_i : in std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); -- |
OUT_PORT_o : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); -- |
PORT_ID_o : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); -- |
READ_STROBE_o : out std_ulogic; |
WRITE_STROBE_o : out std_ulogic; |
-------------------------------------------------------------------------------- |
-- Signaux Speciaux |
-------------------------------------------------------------------------------- |
Freeze_i : in std_ulogic; |
|
-------------------------------------------------------------------------------- |
-- Signaux Wishbone Interface |
-------------------------------------------------------------------------------- |
--RST_I : in std_ulogic; |
--CLK_I : in std_ulogic; |
|
ADR_O : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
DAT_I : in std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
DAT_O : out std_ulogic_vector(GEN_WIDTH_DATA-1 downto 0); |
WE_O : out std_ulogic; |
SEL_O : out std_ulogic_vector(1 downto 0); |
|
STB_O : out std_ulogic; |
ACK_I : in std_ulogic; |
CYC_O : out std_ulogic |
); |
end component; |
|
component cp_ROM_Code |
generic |
( |
GEN_WIDTH_PC : positive := 10; |
GEN_WIDTH_INST : positive := 18 |
); |
port( |
Clk_i : in std_ulogic; |
Address_i : in std_ulogic_vector(GEN_WIDTH_PC-1 downto 0); |
Dout_o : out std_ulogic_vector(GEN_WIDTH_INST-1 downto 0) |
); |
end component; |
|
-------------------------------------------------------------------------------- |
|
-------------------------------------------------------------------------------- |
signal iAddress : std_ulogic_vector(9 downto 0); |
signal iInstruction : std_ulogic_vector(17 downto 0); |
|
signal iReset : std_ulogic := '0'; |
signal iReset_counter : natural range 0 to RESET_LENGTH := RESET_LENGTH; -- VERY BAD SOLUTION |
|
begin |
|
-- ************************** -- |
-- The copyBlaze CPU instance -- |
-- ************************** -- |
processor: cp_copyBlaze |
generic map |
( |
GEN_WIDTH_DATA => GEN_WIDTH_DATA, |
GEN_WIDTH_PC => GEN_WIDTH_PC, |
GEN_WIDTH_INST => GEN_WIDTH_INST, |
|
GEN_DEPTH_STACK => GEN_DEPTH_STACK, |
GEN_DEPTH_BANC => GEN_DEPTH_BANC, |
|
GEN_DEPTH_SCRATCH => GEN_DEPTH_SCRATCH, |
GEN_INT_VECTOR => GEN_INT_VECTOR |
) |
port map( |
-------------------------------------------------------------------------------- |
-- Signaux Systeme |
-------------------------------------------------------------------------------- |
Clk_i => Clk_i, |
Rst_i_n => iReset, |
|
-------------------------------------------------------------------------------- |
-- Signaux Fonctionels |
-------------------------------------------------------------------------------- |
Address_o => iAddress, |
Instruction_i => iInstruction, |
|
Interrupt_i => Interrupt_i, |
Interrupt_Ack_o => Interrupt_Ack_o, |
|
IN_PORT_i => IN_PORT_i, |
OUT_PORT_o => OUT_PORT_o, |
PORT_ID_o => PORT_ID_o, |
READ_STROBE_o => READ_STROBE_o, |
WRITE_STROBE_o => WRITE_STROBE_o, |
-------------------------------------------------------------------------------- |
-- Signaux Speciaux |
-------------------------------------------------------------------------------- |
Freeze_i => Freeze_i, |
|
-------------------------------------------------------------------------------- |
-- Signaux Wishbone Interface |
-------------------------------------------------------------------------------- |
--RST_I => RST_I, |
--CLK_I => CLK_I, |
|
ADR_O => ADR_O, |
DAT_I => DAT_I, |
DAT_O => DAT_O, |
WE_O => WE_O, |
SEL_O => SEL_O, |
|
STB_O => STB_O, |
ACK_I => ACK_I, |
CYC_O => CYC_O |
); |
|
-- *************** -- |
-- ROM code memory -- |
-- *************** -- |
program : cp_ROM_Code |
generic map |
( |
GEN_WIDTH_PC => GEN_WIDTH_PC, |
GEN_WIDTH_INST => GEN_WIDTH_INST |
) |
port map |
( |
Clk_i => Clk_i, |
Address_i => iAddress, |
Dout_o => iInstruction |
); |
|
-------------------------------------------------------------------------------- |
-- Process : ProcessorReset_Proc |
-- Description: Generate the reset of the processor |
-------------------------------------------------------------------------------- |
ProcessorReset_Proc : process(Clk_i) |
begin |
if ( rising_edge(Clk_i) ) then |
if ( iReset_counter = 0 ) then |
iReset <= '1'; |
else |
iReset <= '0'; |
iReset_counter <= iReset_counter - 1; |
end if; |
end if; |
end process ProcessorReset_Proc; |
|
end rtl; |
/cpu/cp_copyBlaze_ecoSystem.vhd
File deleted
\ No newline at end of file
/ip/wb_scope/wb_scope.vhd
0,0 → 1,282
----------------------------------------------------------------------------- |
-- On-chip logic analyzer with wishbone bus for control and data export. |
-- Waveforms are stored in local BlockRAM which size (depth) can be |
-- configured via a generic. |
-- |
-- (c) 2006 by Joerg Bornschein (jb@capsec.org) |
-- All files under GPLv2 |
----------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.ALL; |
use ieee.numeric_std.ALL; |
|
----------------------------------------------------------------------------- |
-- Wishbone LogicAnalyzer --------------------------------------------------- |
entity wb_scope is |
generic ( |
depth : natural := 4096 ); |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- 32 Bit Wishbone Slave |
wb_adr_i : in std_logic_vector(31 downto 0); |
wb_dat_i : in std_logic_vector(31 downto 0); |
wb_dat_o : out std_logic_vector(31 downto 0); |
wb_sel_i : in std_logic_vector( 3 downto 0); |
wb_cyc_i : in std_logic; |
wb_stb_i : in std_logic; |
wb_ack_o : out std_logic; |
wb_we_i : in std_logic; |
wb_irq_o : out std_logic; |
-- I/O ports |
probe : in std_logic_vector(31 downto 0) ); |
end wb_scope; |
|
----------------------------------------------------------------------------- |
-- 0x00000 Status Register: |
-- +-----------------+-------+-------+-------+ |
-- | ... 0 ... | SDONE | IRQEN | SPLEN | |
-- +-----------------+-------+-------+-------+ |
-- |
-- 0x00004 Sample Pointer -- (0x0000 : 0xFFFF) |
-- 0x00008 Sample Counter -- (Stop when 0) |
-- 0x00010 Channel 0 |
-- 0x00011 Channel 1 |
-- 0x00012 Channel 2 |
-- 0x00013 Channel 3 |
-- 0x1???? Data |
----------------------------------------------------------------------------- |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_scope is |
|
----------------------------------------------------------------------------- |
-- Components --------------------------------------------------------------- |
component bram_dp is |
generic ( |
depth : natural ); |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- Port 1 |
we1 : in std_logic; |
addr1 : in std_logic_vector(11 downto 0); |
wdata1 : in std_logic_vector(31 downto 0); |
-- Port 2 |
oe2 : in std_logic; |
addr2 : in std_logic_vector(11 downto 0); |
rdata2 : out std_logic_vector(31 downto 0) ); |
end component; |
|
component mux32 is |
port ( |
input : in std_logic_vector(31 downto 0); |
output : out std_logic; |
sel : in std_logic_vector(4 downto 0) ); |
end component; |
|
----------------------------------------------------------------------------- |
-- Local Signals ------------------------------------------------------------ |
constant ZEROS : std_logic_vector(31 downto 0) := (others => '0'); |
|
signal wbactive : std_logic; |
|
signal status_reg : std_logic_vector(31 downto 0); |
|
signal sp : std_logic_vector(15 downto 0); -- SamplePointer |
signal sc : std_logic_vector(15 downto 0); -- SampleCounter |
signal spen : std_logic; -- Sample Enable |
signal irqen : std_logic; -- IRQ Enable |
signal sdone : std_logic; -- Sampling Done |
|
signal sreg : std_logic_vector(27 downto 0); -- sample register |
signal chan : std_logic_vector( 3 downto 0); -- actual data to be sampled |
signal probe_b : std_logic_vector(31 downto 0); -- buffered probes |
|
signal csel0 : std_logic_vector(4 downto 0); |
signal csel1 : std_logic_vector(4 downto 0); |
signal csel2 : std_logic_vector(4 downto 0); |
signal csel3 : std_logic_vector(4 downto 0); |
|
signal we1 : std_logic; |
signal addr1 : std_logic_vector(11 downto 0); |
signal wdata1: std_logic_vector(31 downto 0); |
|
signal oe2 : std_logic; |
signal addr2 : std_logic_vector(11 downto 0); |
signal rdata2: std_logic_vector(31 downto 0); |
|
signal ram_ack : std_logic; |
|
|
begin |
|
-- Sample RAM --------------------------------------------------------------- |
ram0: bram_dp |
generic map ( |
depth => depth ) |
port map ( |
clk => clk, |
reset => reset, |
-- Port 1 (probe & sample engine (write only)) |
we1 => we1, |
addr1 => addr1, |
wdata1 => wdata1, |
-- Port 2 (Wishbone Access (read only)) |
oe2 => oe2, |
addr2 => addr2, |
rdata2 => rdata2 ); |
|
wbactive <= wb_stb_i and wb_cyc_i; |
|
addr2 <= wb_adr_i(13 downto 2); |
oe2 <= '1' when wbactive='1' and wb_adr_i(19 downto 16)=x"1" else |
'0'; |
|
wb_dat_o <= status_reg when wbactive='1' and wb_adr_i(19 downto 16)=x"0" and wb_adr_i( 7 downto 0)=x"00" else |
ZEROS(31 downto 16) & sp when wbactive='1' and wb_adr_i(19 downto 16)=x"0" and wb_adr_i( 7 downto 0)=x"04" else |
ZEROS(31 downto 16) & sc when wbactive='1' and wb_adr_i(19 downto 16)=x"0" and wb_adr_i( 7 downto 0)=x"08" else |
ZEROS(2 downto 0)&csel3 & |
ZEROS(2 downto 0)&csel2 & |
ZEROS(2 downto 0)&csel1 & |
ZEROS(2 downto 0)&csel0 when wbactive='1' and wb_adr_i(19 downto 16)=x"0" and wb_adr_i( 7 downto 0)=x"10" else |
rdata2 when wbactive='1' and wb_adr_i(19 downto 16)=x"1" else |
(others => '-'); |
|
wb_ack_o <= wbactive and ram_ack when wb_adr_i(19 downto 16)=x"1" else |
wbactive; |
|
wb_irq_o <= sdone and irqen; |
|
status_reg <= ZEROS(31 downto 3) & sdone & irqen & spen; |
|
wbproc: process(reset, clk) is |
variable scv : unsigned(15 downto 0); |
variable spv : unsigned(15 downto 0); |
begin |
if reset='1' then |
spen <= '0'; |
irqen <= '0'; |
sdone <= '0'; |
sp <= (others => '0'); |
sc <= (others => '0'); |
|
csel0 <= (others => '0'); |
csel1 <= (others => '0'); |
csel2 <= (others => '0'); |
csel3 <= (others => '0'); |
|
sreg <= (others => '0'); |
we1 <= '0'; |
ram_ack <= '0'; |
elsif clk'event and clk='1' then |
-- Sample Data |
if spen='1' then |
-- sampling done? |
if sc=ZEROS(15 downto 0) then |
spen <= '0'; |
sdone <= '1'; |
end if; |
|
-- sample into sreg |
if sp(2 downto 0)="111" then |
addr1 <= sp(14 downto 3); |
wdata1 <= sreg & chan; |
we1 <= '1'; |
else |
sreg <= sreg(23 downto 0) & chan; |
we1 <= '0'; |
end if; |
|
-- increase pointer; decrease counter |
scv := unsigned(sc); |
scv := scv - 1; |
sc <= std_logic_vector(scv); |
|
spv := unsigned(sp); |
spv := spv + 1; |
sp <= std_logic_vector(spv); |
end if; |
|
-- WB register write request |
if wbactive='1' and wb_we_i='1' and wb_adr_i(19 downto 16)=x"0" then |
if wb_adr_i(7 downto 0)=x"00" then -- StatusRegister |
spen <= wb_dat_i(0); |
irqen <= wb_dat_i(1); |
sdone <= '0'; |
end if; |
|
if wb_adr_i(7 downto 0)=x"04" then -- SamplePointer |
sp <= wb_dat_i(15 downto 0); |
end if; |
|
if wb_adr_i(7 downto 0)=x"08" then -- SampleCounter |
sc <= wb_dat_i(15 downto 0); |
end if; |
|
if wb_adr_i(7 downto 0)=x"10" then -- Channel Sel |
if wb_sel_i(0)='1' then |
csel3 <= wb_dat_i( 4 downto 0); |
end if; |
|
if wb_sel_i(1)='1' then |
csel2 <= wb_dat_i(12 downto 8); |
end if; |
|
if wb_sel_i(2)='1' then |
csel1 <= wb_dat_i(20 downto 16); |
end if; |
|
if wb_sel_i(3)='1' then |
csel0 <= wb_dat_i(28 downto 24); |
end if; |
end if; |
end if; |
|
-- Buffer read request |
if wbactive='1' and wb_adr_i(19 downto 16)=x"1" then |
ram_ack <= '1' and not ram_ack; |
else |
ram_ack <= '0'; |
end if; |
end if; |
end process; |
|
-- Probe buffering and muxing ----------------------------------------------- |
bufproc: process(clk, reset) is -- buffer probes BEFORE mux (timing) |
begin |
if reset='1' then |
probe_b <= (others => '0'); |
elsif clk'event and clk='1' then |
probe_b <= probe; |
end if; |
end process; |
|
|
mux0: mux32 -- Channel 0 |
port map ( |
input => probe_b, |
output => chan(0), |
sel => csel0 ); |
|
mux1: mux32 -- Channel 1 |
port map ( |
input => probe_b, |
output => chan(1), |
sel => csel1 ); |
|
mux2: mux32 -- Channel 2 |
port map ( |
input => probe_b, |
output => chan(2), |
sel => csel2 ); |
|
mux3: mux32 -- Channel 3 |
port map ( |
input => probe_b, |
output => chan(3), |
sel => csel3 ); |
|
end rtl; |
|
/ip/wb_scope/bram_dp.vhd
0,0 → 1,56
----------------------------------------------------------------------------- |
-- Dual Port Block Ram (technology independent description) |
-- (c) 2006 Joerg Bornschein (jb@capsec.org) |
-- All files under GPLv2 |
----------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.ALL; |
use ieee.numeric_std.all; |
|
entity bram_dp is |
generic ( |
depth : natural := 4096 ); |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- Port 1 |
we1 : in std_logic; |
addr1 : in std_logic_vector(11 downto 0); |
wdata1 : in std_logic_vector(31 downto 0); |
-- Port 2 |
oe2 : in std_logic; |
addr2 : in std_logic_vector(11 downto 0); |
rdata2 : out std_logic_vector(31 downto 0) ); |
end bram_dp; |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of bram_dp is |
|
type mem_type is array(0 to depth-1) of std_logic_vector(31 downto 0); |
signal mem : mem_type := (others => x"00000000" ); |
|
begin |
|
memproc: process (clk) is |
variable a1 : integer; |
variable a2 : integer; |
begin |
if reset='1' then |
null; |
elsif clk'event and clk='1' then |
if we1='1' then -- Port 1 |
a1 := to_integer(unsigned(addr1)); |
mem(a1) <= wdata1; |
end if; |
|
if oe2='1' then -- Port 2 |
a2 := to_integer(unsigned(addr2)); |
rdata2 <= mem(a2); |
end if; |
end if; |
end process; |
|
end rtl; |
|
/ip/wb_scope/mux32.vhd
0,0 → 1,30
----------------------------------------------------------------------------- |
-- 32-to-1 MUXer ------------------------------------------------------------ |
-- |
-- (c) 2006 by Joerg Bornschein (jb@capsec.org) |
-- All files under GPLv2 |
----------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.ALL; |
use ieee.numeric_std.ALL; |
|
|
----------------------------------------------------------------------------- |
-- 32-to-1 MUXer ------------------------------------------------------------ |
entity mux32 is |
port ( |
input : in std_logic_vector(31 downto 0); |
output : out std_logic; |
sel : in std_logic_vector(4 downto 0) ); |
end entity; |
|
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of mux32 is |
signal usel : unsigned(4 downto 0); |
begin |
|
output <= input( to_integer(unsigned(sel)) ); |
|
end architecture rtl; |
/ip/wb_uart/uart_rx.vhd
0,0 → 1,102
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
----------------------------------------------------------------------------- |
-- UART Receiver ------------------------------------------------------------ |
entity uart_rx is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
dout : out std_ulogic_vector( 7 downto 0); |
avail : out std_ulogic; |
error : out std_ulogic; |
clear : in std_ulogic; |
-- |
rxd : in std_ulogic ); |
end uart_rx; |
|
----------------------------------------------------------------------------- |
-- Implemenattion ----------------------------------------------------------- |
architecture rtl of uart_rx is |
|
-- Signals |
signal bitcount : integer range 0 to 10; |
signal count : unsigned(15 downto 0); |
signal shiftreg : std_ulogic_vector(7 downto 0); |
signal rxh : std_ulogic_vector(2 downto 0); |
signal rxd2 : std_ulogic; |
|
begin |
|
proc: process(clk, reset) is |
begin |
if clk'event and clk='1' then |
if reset='1' then |
count <= (others => '0'); |
bitcount <= 0; |
error <= '0'; |
avail <= '0'; |
else |
if clear='1' then |
error <= '0'; |
avail <= '0'; |
end if; |
|
if count/=0 then |
count <= count - 1; |
else |
if bitcount=0 then -- wait for startbit |
if rxd2='0' then -- FOUND |
count <= unsigned("0" & divisor(15 downto 1) ); |
bitcount <= bitcount + 1; |
end if; |
elsif bitcount=1 then -- sample mid of startbit |
if rxd2='0' then -- OK |
count <= unsigned(divisor); |
bitcount <= bitcount + 1; |
shiftreg <= "00000000"; |
else -- ERROR |
error <= '1'; |
bitcount <= 0; |
end if; |
elsif bitcount=10 then -- stopbit |
-- if rxd2='1' then -- OK |
bitcount <= 0; |
dout <= shiftreg; |
avail <= '1'; |
-- else -- ERROR |
-- error <= '1'; |
-- end if; |
else |
shiftreg(6 downto 0) <= shiftreg(7 downto 1); |
shiftreg(7) <= rxd2; |
count <= unsigned(divisor); |
bitcount <= bitcount + 1; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Sync incoming RXD (anti metastable) -------------------------------------- |
syncproc: process(reset, clk) is |
begin |
if reset='1' then |
rxh <= (others => '1'); |
rxd2 <= '1'; |
elsif clk'event and clk='1' then |
rxh <= rxh(1 downto 0) & rxd; |
if rxh="111" then |
rxd2 <= '1'; |
elsif rxh="000" then |
rxd2 <= '0'; |
end if; |
end if; |
end process; |
|
end rtl; |
|
/ip/wb_uart/uart_tx.vhd
0,0 → 1,70
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
----------------------------------------------------------------------------- |
-- UART Transmitter --------------------------------------------------------- |
entity uart_tx is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
din : in std_ulogic_vector( 7 downto 0); |
wr : in std_ulogic; |
busy : out std_ulogic; |
-- |
txd : out std_ulogic ); |
end uart_tx; |
|
|
----------------------------------------------------------------------------- |
-- Implemenattion ----------------------------------------------------------- |
architecture rtl of uart_tx is |
|
-- Signals |
signal bitcount : integer range 0 to 10; |
signal count : unsigned(15 downto 0); |
signal shiftreg : std_ulogic_vector(7 downto 0); |
|
begin |
|
proc: process(clk) |
begin |
if clk'event and clk='1' then |
if reset='1' then |
count <= (others => '0'); |
bitcount <= 0; |
busy <= '0'; |
txd <= '1'; |
else |
if count/=0 then |
count <= count - 1; |
else |
if bitcount=0 then |
if wr='1' then -- START BIT |
shiftreg <= din; |
busy <= '1'; |
txd <= '0'; |
bitcount <= bitcount + 1; |
count <= unsigned(divisor); |
else |
busy <= '0'; |
end if; |
elsif bitcount=9 then -- STOP BIT |
txd <= '1'; |
bitcount <= 0; |
count <= unsigned(divisor); |
else -- DATA BIT |
shiftreg(6 downto 0) <= shiftreg(7 downto 1); |
txd <= shiftreg(0); |
bitcount <= bitcount + 1; |
count <= unsigned(divisor); |
end if; |
end if; |
end if; |
end if; |
end process; |
|
end rtl; |
|
/ip/wb_uart/wb_uart_8.vhd
0,0 → 1,189
----------------------------------------------------------------------------- |
-- Wishbone UART ------------------------------------------------------------ |
-- (c) 2007 Joerg Bornschein (jb@capsec.org) |
-- |
-- All files under GPLv2 -- please contact me if you use this component |
----------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
----------------------------------------------------------------------------- |
-- Wishbone UART ------------------------------------------------------------ |
entity wb_uart_8 is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- Wishbone slave |
wb_adr_i : in std_ulogic_vector( 7 downto 0); |
wb_dat_i : in std_ulogic_vector( 7 downto 0); |
wb_dat_o : out std_ulogic_vector( 7 downto 0); |
wb_cyc_i : in std_ulogic; |
wb_stb_i : in std_ulogic; |
wb_ack_o : out std_ulogic; |
wb_we_i : in std_ulogic; |
wb_rxirq_o : out std_ulogic; |
wb_txirq_o : out std_ulogic; |
-- Serial I/O ports |
uart_rx : in std_ulogic; |
uart_tx : out std_ulogic |
); |
end wb_uart_8; |
|
----------------------------------------------------------------------------- |
-- 0x00 Status Register |
-- 0x04 Divisor Register |
-- 0x08 RX / TX Data |
-- |
-- Status Register: |
-- |
-- +-------------+----------+----------+---------+---------+ |
-- | ... 0 ... | TX_IRQEN | RX_IRQEN | TX_BUSY | RX_FULL | |
-- +-------------+----------+----------+---------+---------+ |
-- |
-- Divisor Register: |
-- Example: 115200 Baud with clk beeing 50MHz: 50MHz/115200 = 434 |
-- |
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_uart_8 is |
|
----------------------------------------------------------------------------- |
-- Components --------------------------------------------------------------- |
component myuart is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
txdata : in std_ulogic_vector( 7 downto 0); |
rxdata : out std_ulogic_vector( 7 downto 0); |
wr : in std_ulogic; |
rd : in std_ulogic; |
tx_avail : out std_ulogic; |
tx_busy : out std_ulogic; |
rx_avail : out std_ulogic; |
rx_full : out std_ulogic; |
rx_error : out std_ulogic; |
-- |
uart_rxd : in std_ulogic; |
uart_txd : out std_ulogic ); |
end component; |
|
|
----------------------------------------------------------------------------- |
-- Local Signals ------------------------------------------------------------ |
constant ADDR_STATUS : std_ulogic_vector(7 downto 0) := x"00"; |
constant ADDR_DIV_LOW : std_ulogic_vector(7 downto 0) := x"04"; |
constant ADDR_DIV_HIGH : std_ulogic_vector(7 downto 0) := x"05"; |
constant ADDR_DATA : std_ulogic_vector(7 downto 0) := x"08"; |
|
constant ZEROS : std_ulogic_vector(31 downto 0) := (others => '0'); |
|
signal active : std_ulogic; |
signal activeLast : std_ulogic; |
signal ack : std_ulogic; |
|
signal wr : std_ulogic; |
signal rd : std_ulogic; |
signal rx_avail : std_ulogic; |
signal tx_avail : std_ulogic; |
signal rxdata : std_ulogic_vector(7 downto 0); |
signal txdata : std_ulogic_vector(7 downto 0); |
|
signal status_reg : std_ulogic_vector( 7 downto 0); |
signal data_reg : std_ulogic_vector( 7 downto 0); |
--signal div_reg : std_ulogic_vector( 7 downto 0); |
|
signal tx_irqen : std_ulogic; |
signal rx_irqen : std_ulogic; |
signal divisor : std_ulogic_vector(15 downto 0); |
|
begin |
|
-- Instantiate actual UART engine |
uart0: myuart |
port map ( |
clk => clk, |
reset => reset, |
-- Sync Interface |
divisor => divisor, |
txdata => txdata, |
rxdata => rxdata, |
wr => wr, |
rd => rd, |
tx_avail => tx_avail, |
tx_busy => open, |
rx_avail => rx_avail, |
rx_full => open, |
rx_error => open, |
-- Async Interface |
uart_txd => uart_tx, |
uart_rxd => uart_rx ); |
|
|
-- Status & divisor register + Wishbine glue logic |
status_reg <= ZEROS( 7 downto 4) & tx_irqen & rx_irqen & not tx_avail & rx_avail; |
data_reg <= rxdata; |
--div_reg <= ZEROS(31 downto 16) & divisor; |
|
-- Bus cycle? |
active <= wb_stb_i and wb_cyc_i; |
|
wb_dat_o <= status_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i=ADDR_STATUS else |
divisor( 7 downto 0) when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i=ADDR_DIV_LOW else |
divisor(15 downto 8) when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i=ADDR_DIV_HIGH else |
data_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i=ADDR_DATA else |
(others => '0'); |
|
rd <= '1' when (active='1' or ack='1') and wb_adr_i=ADDR_DATA and wb_we_i='0' else |
'0'; |
|
wr <= '1' when (active='1' or ack='1') and wb_adr_i=ADDR_DATA and wb_we_i='1' else |
'0'; |
|
txdata <= wb_dat_i; |
wb_ack_o <= ack; |
|
-- Handle Wishbone write request (and reset condition) |
proc: process(reset, clk) is |
begin |
if clk'event and clk='1' then |
if reset='1' then |
tx_irqen <= '0'; |
rx_irqen <= '0'; |
divisor <= (others => '1'); |
else |
|
if active='1' then |
if activeLast='0' then |
activeLast <= '1'; |
ack <= '0'; |
else |
activeLast <= '0'; |
ack <= '1'; |
end if; |
else |
ack <= '0'; |
activeLast <= '0'; |
end if; |
|
if active='1' and wb_we_i='1' then |
if wb_adr_i=ADDR_STATUS then -- write to status register |
tx_irqen <= wb_dat_i(3); |
rx_irqen <= wb_dat_i(2); |
elsif wb_adr_i=ADDR_DIV_LOW then -- write to divisor register low |
divisor( 7 downto 0) <= wb_dat_i; |
elsif wb_adr_i=ADDR_DIV_HIGH then -- write to divisor register high |
divisor(15 downto 8) <= wb_dat_i; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
-- Generate interrupts when enabled |
wb_rxirq_o <= rx_avail and rx_irqen; |
wb_txirq_o <= tx_avail and tx_irqen; |
|
end rtl; |
/ip/wb_uart/uart.vhd
0,0 → 1,149
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
----------------------------------------------------------------------------- |
-- UART --------------------------------------------------------------------- |
entity myuart is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
txdata : in std_ulogic_vector( 7 downto 0); |
rxdata : out std_ulogic_vector( 7 downto 0); |
wr : in std_ulogic; |
rd : in std_ulogic; |
tx_avail : out std_ulogic; |
tx_busy : out std_ulogic; |
rx_avail : out std_ulogic; |
rx_full : out std_ulogic; |
rx_error : out std_ulogic; |
-- |
uart_rxd : in std_ulogic; |
uart_txd : out std_ulogic ); |
end myuart; |
|
----------------------------------------------------------------------------- |
-- implementation ----------------------------------------------------------- |
architecture rtl of myuart is |
|
----------------------------------------------------------------------------- |
-- component declarations --------------------------------------------------- |
component uart_rx is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
dout : out std_ulogic_vector(7 downto 0); |
avail : out std_ulogic; |
error : out std_ulogic; |
clear : in std_ulogic; |
-- |
rxd : in std_ulogic ); |
end component; |
|
component uart_tx is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- |
divisor : in std_ulogic_vector(15 downto 0); |
din : in std_ulogic_vector(7 downto 0); |
wr : in std_ulogic; |
busy : out std_ulogic; |
-- |
txd : out std_ulogic ); |
end component; |
|
----------------------------------------------------------------------------- |
-- local signals ------------------------------------------------------------ |
signal utx_busy : std_ulogic; |
signal utx_wr : std_ulogic; |
|
signal urx_dout : std_ulogic_vector(7 downto 0); |
signal urx_avail : std_ulogic; |
signal urx_clear : std_ulogic; |
signal urx_error : std_ulogic; |
|
signal txbuf : std_ulogic_vector(7 downto 0); |
signal txbuf_full : std_ulogic; |
signal rxbuf : std_ulogic_vector(7 downto 0); |
signal rxbuf_full : std_ulogic; |
|
begin |
|
iotxproc: process(clk) is |
begin |
if clk'event and clk='1' then |
if reset='1' then |
utx_wr <= '0'; |
txbuf_full <= '0'; |
|
urx_clear <= '0'; |
rxbuf_full <= '0'; |
else |
-- TX Buffer Logic |
if wr='1' and not txbuf_full='1' then |
txbuf <= txdata; |
txbuf_full <= '1'; |
end if; |
|
if txbuf_full='1' and utx_busy='0' then |
utx_wr <= '1'; |
txbuf_full <= '0'; |
else |
utx_wr <= '0'; |
end if; |
|
-- RX Buffer Logic |
if rd='1' then |
rxbuf_full <= '0'; |
end if; |
|
if urx_avail='1' and rxbuf_full='0' then |
rxbuf <= urx_dout; |
rxbuf_full <= '1'; |
urx_clear <= '1'; |
else |
urx_clear <= '0'; |
end if; |
end if; |
end if; |
end process; |
|
rxdata <= rxbuf; |
rx_avail <= rxbuf_full and not rd; |
rx_full <= rxbuf_full and urx_avail and not rd; |
rx_error <= urx_error; |
|
tx_busy <= utx_busy or txbuf_full; -- or wr; |
tx_avail <= not txbuf_full; |
|
-- Instantiate RX and TX engine |
uart_rx0: uart_rx |
port map ( |
clk => clk, |
reset => reset, |
-- |
divisor => divisor, |
dout => urx_dout, |
avail => urx_avail, |
error => urx_error, |
clear => urx_clear, |
-- |
rxd => uart_rxd ); |
|
uart_tx0: uart_tx |
port map ( |
clk => clk, |
reset => reset, |
-- |
divisor => divisor, |
din => txbuf, |
wr => utx_wr, |
busy => utx_busy, |
-- |
txd => uart_txd ); |
end rtl; |
/ip/wb_uart/wb_uart.vhd
0,0 → 1,182
----------------------------------------------------------------------------- |
-- Wishbone UART ------------------------------------------------------------ |
-- (c) 2007 Joerg Bornschein (jb@capsec.org) |
-- |
-- All files under GPLv2 -- please contact me if you use this component |
----------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
----------------------------------------------------------------------------- |
-- Wishbone UART ------------------------------------------------------------ |
entity wb_uart is |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- Wishbone slave |
wb_adr_i : in std_logic_vector(31 downto 0); |
wb_dat_i : in std_logic_vector(31 downto 0); |
wb_dat_o : out std_logic_vector(31 downto 0); |
wb_sel_i : in std_logic_vector( 3 downto 0); |
wb_cyc_i : in std_logic; |
wb_stb_i : in std_logic; |
wb_ack_o : out std_logic; |
wb_we_i : in std_logic; |
wb_rxirq_o : out std_logic; |
wb_txirq_o : out std_logic; |
-- Serial I/O ports |
uart_rx : in std_logic; |
uart_tx : out std_logic ); |
end wb_uart; |
|
----------------------------------------------------------------------------- |
-- 0x00 Status Register |
-- 0x04 Divisor Register |
-- 0x08 RX / TX Data |
-- |
-- Status Register: |
-- |
-- +-------------+----------+----------+---------+---------+ |
-- | ... 0 ... | TX_IRQEN | RX_IRQEN | TX_BUSY | RX_FULL | |
-- +-------------+----------+----------+---------+---------+ |
-- |
-- Divisor Register: |
-- Example: 115200 Baud with clk beeing 50MHz: 50MHz/115200 = 434 |
-- |
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_uart is |
|
----------------------------------------------------------------------------- |
-- Components --------------------------------------------------------------- |
component myuart is |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- |
divisor : in std_logic_vector(15 downto 0); |
txdata : in std_logic_vector( 7 downto 0); |
rxdata : out std_logic_vector( 7 downto 0); |
wr : in std_logic; |
rd : in std_logic; |
tx_avail : out std_logic; |
tx_busy : out std_logic; |
rx_avail : out std_logic; |
rx_full : out std_logic; |
rx_error : out std_logic; |
-- |
uart_rxd : in std_logic; |
uart_txd : out std_logic ); |
end component; |
|
|
----------------------------------------------------------------------------- |
-- Local Signals ------------------------------------------------------------ |
|
constant ZEROS : std_logic_vector(31 downto 0) := (others => '0'); |
|
signal active : std_logic; |
signal activeLast : std_logic; |
signal ack : std_logic; |
|
signal wr : std_logic; |
signal rd : std_logic; |
signal rx_avail : std_logic; |
signal tx_avail : std_logic; |
signal rxdata : std_logic_vector(7 downto 0); |
signal txdata : std_logic_vector(7 downto 0); |
|
signal status_reg : std_logic_vector(31 downto 0); |
signal data_reg : std_logic_vector(31 downto 0); |
signal div_reg : std_logic_vector(31 downto 0); |
|
signal tx_irqen : std_logic; |
signal rx_irqen : std_logic; |
signal divisor : std_logic_vector(15 downto 0); |
|
begin |
|
-- Instantiate actual UART engine |
uart0: myuart |
port map ( |
clk => clk, |
reset => reset, |
-- Sync Interface |
divisor => divisor, |
txdata => txdata, |
rxdata => rxdata, |
wr => wr, |
rd => rd, |
tx_avail => tx_avail, |
tx_busy => open, |
rx_avail => rx_avail, |
rx_full => open, |
rx_error => open, |
-- Async Interface |
uart_txd => uart_tx, |
uart_rxd => uart_rx ); |
|
|
-- Status & divisor register + Wishbine glue logic |
status_reg <= ZEROS(31 downto 4) & tx_irqen & rx_irqen & not tx_avail & rx_avail; |
data_reg <= ZEROS(31 downto 8) & rxdata; |
div_reg <= ZEROS(31 downto 16) & divisor; |
|
-- Bus cycle? |
active <= wb_stb_i and wb_cyc_i; |
|
wb_dat_o <= status_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"0" else |
div_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"4" else |
data_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" else |
(others => '0'); |
|
rd <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='0' else |
'0'; |
|
wr <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='1' else |
'0'; |
|
txdata <= wb_dat_i(7 downto 0); |
wb_ack_o <= ack; |
|
-- Handle Wishbone write request (and reset condition) |
proc: process(reset, clk) is |
begin |
if clk'event and clk='1' then |
if reset='1' then |
tx_irqen <= '0'; |
rx_irqen <= '0'; |
divisor <= (others => '1'); |
else |
|
if active='1' then |
if activeLast='0' then |
activeLast <= '1'; |
ack <= '0'; |
else |
activeLast <= '0'; |
ack <= '1'; |
end if; |
else |
ack <= '0'; |
activeLast <= '0'; |
end if; |
|
if active='1' and wb_we_i='1' then |
if wb_adr_i(3 downto 0)=x"0" then -- write to status register |
tx_irqen <= wb_dat_i(3); |
rx_irqen <= wb_dat_i(2); |
elsif wb_adr_i(3 downto 0)=x"4" then -- write to divisor register |
divisor <= wb_dat_i(15 downto 0); |
end if; |
end if; |
end if; |
end if; |
end process; |
|
-- Generate interrupts when enabled |
wb_rxirq_o <= rx_avail and rx_irqen; |
wb_txirq_o <= tx_avail and tx_irqen; |
|
end rtl; |
/ip/wb_gpio/wb_gpio_08.vhd
0,0 → 1,76
----------------------------------------------------------------------------- |
-- Wishbone GPIO ------------------------------------------------------------ |
library ieee; |
use ieee.std_logic_1164.ALL; |
use ieee.numeric_std.all; |
|
entity wb_gpio_08 is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- Wishbone bus |
wb_adr_i : in std_ulogic_vector(7 downto 0); |
wb_dat_i : in std_ulogic_vector(7 downto 0); |
wb_dat_o : out std_ulogic_vector(7 downto 0); |
wb_cyc_i : in std_ulogic; |
wb_stb_i : in std_ulogic; |
wb_ack_o : out std_ulogic; |
wb_we_i : in std_ulogic; |
-- I/O ports |
iport : in std_ulogic_vector(7 downto 0); |
oport : out std_ulogic_vector(7 downto 0) |
); |
end wb_gpio_08; |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_gpio_08 is |
|
constant OPORT_ADDR : std_ulogic_vector(7 downto 0) := x"04"; |
constant IPORT_ADDR : std_ulogic_vector(7 downto 0) := x"01"; |
|
signal wbactive : std_ulogic; |
|
signal oport_reg : std_ulogic_vector(7 downto 0); |
signal iport_reg : std_ulogic_vector(7 downto 0); |
|
begin |
|
oport <= oport_reg; |
|
-- synchronize incoming signals (anti-meta-state) |
syncproc: process(clk) is |
begin |
if (rising_edge(clk)) then |
iport_reg <= iport; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Wishbone handling -------------------------------------------------------- |
|
wb_ack_o <= wb_stb_i and wb_cyc_i; |
|
wb_dat_o <= iport_reg when ( wb_stb_i='1' and wb_cyc_i='1' and wb_adr_i=IPORT_ADDR ) else |
oport_reg when ( wb_stb_i='1' and wb_cyc_i='1' and wb_adr_i=OPORT_ADDR ) else |
(others => '-'); |
|
writeproc: process (reset, clk) is |
|
begin |
if (reset='0') then |
oport_reg <= (others => '0'); |
elsif ( rising_edge(clk)) then |
if (wb_stb_i='1' and wb_cyc_i='1' and wb_we_i='1') then |
|
-- decode WB_ADR_I -- |
if (wb_adr_i=OPORT_ADDR) then |
oport_reg <= wb_dat_i; |
end if; |
|
end if; |
end if; |
end process; |
|
end rtl; |
|
/ip/wb_gpio/WBOPRT08.vhd
0,0 → 1,39
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity WBOPRT08 is |
port( |
-- WISHBONE SLAVE interface: |
ACK_O : out std_ulogic; |
CLK_I : in std_ulogic; |
DAT_I : in std_ulogic_vector( 7 downto 0 ); |
DAT_O : out std_ulogic_vector( 7 downto 0 ); |
RST_I : in std_ulogic; |
STB_I : in std_ulogic; |
WE_I : in std_ulogic; |
-- Output port (non-WISHBONE signals): |
PRT_O : out std_ulogic_vector( 7 downto 0 ) |
); |
end entity WBOPRT08; |
architecture WBOPRT081 of WBOPRT08 is |
signal Q: std_ulogic_vector( 7 downto 0 ); |
begin |
REG: process( CLK_I ) |
begin |
if( rising_edge( CLK_I ) ) then |
if( RST_I = '1' ) then |
Q <= B"00000000"; |
elsif( (STB_I and WE_I) = '1' ) then |
Q <= DAT_I( 7 downto 0 ); |
else |
Q <= Q; |
end if; |
end if; |
end process REG; |
|
ACK_O <= STB_I; |
DAT_O <= Q; |
PRT_O <= Q; |
|
end architecture WBOPRT081; |
/ip/wb_gpio/wb_gpio.vhd
0,0 → 1,86
----------------------------------------------------------------------------- |
-- Wishbone GPIO ------------------------------------------------------------ |
library ieee; |
use ieee.std_logic_1164.ALL; |
|
entity wb_gpio is |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- Wishbone bus |
wb_adr_i : in std_logic_vector(31 downto 0); |
wb_dat_i : in std_logic_vector(31 downto 0); |
wb_dat_o : out std_logic_vector(31 downto 0); |
wb_sel_i : in std_logic_vector( 3 downto 0); |
wb_cyc_i : in std_logic; |
wb_stb_i : in std_logic; |
wb_ack_o : out std_logic; |
wb_we_i : in std_logic; |
-- I/O ports |
iport : in std_logic_vector(31 downto 0); |
oport : out std_logic_vector(31 downto 0) ); |
end wb_gpio; |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_gpio is |
|
signal wbactive : std_logic; |
|
signal oport_reg : std_logic_vector(31 downto 0); |
signal iport_reg : std_logic_vector(31 downto 0); |
|
begin |
|
oport <= oport_reg; |
|
-- synchronize incoming signals (anti-meta-state) |
syncproc: process(clk) is |
begin |
if clk'event and clk='1' then |
iport_reg <= iport; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Wishbone handling -------------------------------------------------------- |
|
wb_ack_o <= wb_stb_i and wb_cyc_i; |
|
wb_dat_o <= iport_reg when wb_stb_i='1' and wb_cyc_i='1' and wb_adr_i(3 downto 0)=x"0" else |
oport_reg when wb_stb_i='1' and wb_cyc_i='1' and wb_adr_i(3 downto 0)=x"4" else |
(others => '-'); |
|
writeproc: process (reset, clk) is |
variable val : std_logic_vector(31 downto 0); |
begin |
if reset='1' then |
oport_reg <= (others => '0'); |
elsif clk'event and clk='1' then |
if wb_stb_i='1' and wb_cyc_i='1' and wb_we_i='1' then |
|
-- decode WB_SEL_I -- |
if wb_sel_i(3)='1' then |
val(31 downto 24) := wb_dat_i(31 downto 24); |
end if; |
if wb_sel_i(2)='1' then |
val(23 downto 16) := wb_dat_i(23 downto 16); |
end if; |
if wb_sel_i(1)='1' then |
val(15 downto 8) := wb_dat_i(15 downto 8); |
end if; |
if wb_sel_i(0)='1' then |
val( 7 downto 0) := wb_dat_i( 7 downto 0); |
end if; |
|
-- decode WB_ADR_I -- |
if wb_adr_i(3 downto 0)=x"4" then |
oport_reg <= val; |
end if; |
|
end if; |
end if; |
end process; |
|
end rtl; |
|
/ip/wb_timer/wb_timer_8.vhd
0,0 → 1,170
----------------------------------------------------------------------------- |
-- Wishbone TIMER 8bit ------------------------------------------------------ |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity wb_timer_8 is |
port ( |
clk : in std_ulogic; |
reset : in std_ulogic; |
-- Wishbone bus |
wb_adr_i : in std_ulogic_vector(7 downto 0); |
wb_dat_i : in std_ulogic_vector(7 downto 0); |
wb_dat_o : out std_ulogic_vector(7 downto 0); |
wb_cyc_i : in std_ulogic; |
wb_stb_i : in std_ulogic; |
wb_ack_o : out std_ulogic; |
wb_we_i : in std_ulogic; |
wb_irq0_o: out std_ulogic; |
wb_irq1_o: out std_ulogic ); |
end wb_timer_8; |
|
----------------------------------------------------------------------------- |
-- 0x00: TCR0 Timer Control and Status Register |
-- 0x04: COMPARE0 |
-- 0x08: COUNTER0 |
-- 0x0C: TCR1 |
-- 0x10: COMPARE1 |
-- 0x14: COUNTER1 |
-- |
-- TCRx: |
-- |
-- +-----------------------------------+-----+-----+--------+-------+ |
-- | ZEROs ( 7 downto 4) | en0 | ar0 | irq0en | trig0 | |
-- +-----------------------------------+-----+-----+--------+-------+ |
-- |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_timer_8 is |
constant ADDR_TRC0 : std_ulogic_vector(7 downto 0) := x"00"; |
constant ADDR_COMPARE0 : std_ulogic_vector(7 downto 0) := x"04"; |
constant ADDR_COUNTER0 : std_ulogic_vector(7 downto 0) := x"08"; |
constant ADDR_TRC1 : std_ulogic_vector(7 downto 0) := x"0C"; |
constant ADDR_COMPARE1 : std_ulogic_vector(7 downto 0) := x"10"; |
constant ADDR_COUNTER1 : std_ulogic_vector(7 downto 0) := x"14"; |
|
signal wbactive : std_ulogic; |
|
signal counter0 : unsigned(7 downto 0); |
signal counter1 : unsigned(7 downto 0); |
|
signal compare0 : unsigned(7 downto 0); |
signal compare1 : unsigned(7 downto 0); |
|
signal en0, en1 : std_ulogic; -- Enable counter |
signal ar0, ar1 : std_ulogic; -- Auto Reload |
signal trig0, trig1 : std_ulogic; -- Triggered |
|
signal irq0en, irq1en: std_ulogic; -- Enable Interrupt |
|
signal tcr0, tcr1 : std_ulogic_vector(7 downto 0); |
|
|
begin |
|
----------------------------------------------------------------------------- |
-- Wishbone handling -------------------------------------------------------- |
wbactive <= wb_stb_i and wb_cyc_i; |
|
wb_ack_o <= wbactive; |
|
wb_dat_o <= tcr0 when wbactive='1' and wb_adr_i=ADDR_TRC0 else |
std_ulogic_vector(compare0) when wbactive='1' and wb_adr_i=ADDR_COMPARE0 else |
std_ulogic_vector(counter0) when wbactive='1' and wb_adr_i=ADDR_COUNTER0 else |
tcr1 when wbactive='1' and wb_adr_i=ADDR_TRC1 else |
std_ulogic_vector(compare1) when wbactive='1' and wb_adr_i=ADDR_COMPARE1 else |
std_ulogic_vector(counter1) when wbactive='1' and wb_adr_i=ADDR_COUNTER1 else |
(others => '-'); |
|
wb_irq0_o <= trig0 and irq0en; |
wb_irq1_o <= trig1 and irq1en; |
|
tcr0 <= "0000" & en0 & ar0 & irq0en & trig0; |
tcr1 <= "0000" & en1 & ar1 & irq1en & trig1; |
|
timerproc: process (reset, clk) is |
variable val : std_ulogic_vector(7 downto 0); |
begin |
if reset='1' then |
en0 <= '0'; -- enable |
en1 <= '0'; |
ar0 <= '0'; -- auto reload |
ar1 <= '0'; |
trig0 <= '0'; -- triggered |
trig1 <= '0'; |
irq0en <= '0'; -- IRQ enable |
irq1en <= '0'; |
compare0 <= TO_UNSIGNED(0, 8); -- compare |
compare1 <= TO_UNSIGNED(0, 8); |
counter0 <= TO_UNSIGNED(0, 8); -- actual counter |
counter1 <= TO_UNSIGNED(0, 8); |
elsif clk'event and clk='1' then |
|
-- Reset trigX on TCR access -------------------------------- |
if wbactive='1' and wb_adr_i=x"00" then |
trig0 <= '0'; |
end if; |
if wbactive='1' and wb_adr_i=x"0C" then |
trig1 <= '0'; |
end if; |
|
-- WB write register ---------------------------------------- |
if wbactive='1' and wb_we_i='1' then |
|
val := wb_dat_i; |
|
-- decode WB_ADR_I -- |
if wb_adr_i=ADDR_TRC0 then |
en0 <= val(3); |
ar0 <= val(2); |
irq0en <= val(1); |
elsif wb_adr_i=ADDR_COMPARE0 then |
compare0 <= unsigned(val); |
elsif wb_adr_i=ADDR_COUNTER0 then |
counter0 <= unsigned(val); |
elsif wb_adr_i=ADDR_TRC1 then |
en1 <= val(3); |
ar1 <= val(2); |
irq1en <= val(1); |
elsif wb_adr_i=ADDR_COMPARE1 then |
compare1 <= unsigned(val); |
elsif wb_adr_i=ADDR_COUNTER1 then |
counter1 <= unsigned(val); |
end if; |
end if; |
|
|
-- timer0 --------------------------------------------------- |
if en0='1' then |
if counter0 = compare0 then |
trig0 <= '1'; |
if ar0='1' then |
counter0 <= to_unsigned(1, 8); |
else |
en0 <= '0'; |
end if; |
else |
counter0 <= counter0 + 1; |
end if; |
end if; |
|
-- timer1 --------------------------------------------------- |
if en1='1' then |
if counter1 = compare1 then |
trig1 <= '1'; |
if ar1='1' then |
counter1 <= to_unsigned(1, 8); |
else |
en1 <= '0'; |
end if; |
else |
counter1 <= counter1 + 1; |
end if; |
end if; |
|
end if; |
end process; |
|
end rtl; |
/ip/wb_timer/wb_timer.vhd
0,0 → 1,177
----------------------------------------------------------------------------- |
-- Wishbone TIMER ----------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity wb_timer is |
port ( |
clk : in std_logic; |
reset : in std_logic; |
-- Wishbone bus |
wb_adr_i : in std_logic_vector(31 downto 0); |
wb_dat_i : in std_logic_vector(31 downto 0); |
wb_dat_o : out std_logic_vector(31 downto 0); |
wb_sel_i : in std_logic_vector( 3 downto 0); |
wb_cyc_i : in std_logic; |
wb_stb_i : in std_logic; |
wb_ack_o : out std_logic; |
wb_we_i : in std_logic; |
wb_irq0_o: out std_logic; |
wb_irq1_o: out std_logic ); |
end wb_timer; |
|
----------------------------------------------------------------------------- |
-- 0x00: TCR0 Timer Control and Status Register |
-- 0x04: COMPARE0 |
-- 0x08: COUNTER0 |
-- 0x0C: TCR1 |
-- 0x10: COMPARE1 |
-- 0x14: COUNTER1 |
-- |
-- TCRx: |
-- |
-- +-----------------------------------+-----+-----+--------+-------+ |
-- | ZEROs (31 downto 4) | en0 | ar0 | irq0en | trig0 | |
-- +-----------------------------------+-----+-----+--------+-------+ |
-- |
|
----------------------------------------------------------------------------- |
-- Implementation ----------------------------------------------------------- |
architecture rtl of wb_timer is |
|
signal wbactive : std_logic; |
|
signal counter0 : unsigned(31 downto 0); |
signal counter1 : unsigned(31 downto 0); |
|
signal compare0 : unsigned(31 downto 0); |
signal compare1 : unsigned(31 downto 0); |
|
signal en0, en1 : std_logic; -- Enable counter |
signal ar0, ar1 : std_logic; -- Auto Reload |
signal trig0, trig1 : std_logic; -- Triggered |
|
signal irq0en, irq1en: std_logic; -- Enable Interrupt |
|
signal tcr0, tcr1 : std_logic_vector(31 downto 0); |
|
|
begin |
|
----------------------------------------------------------------------------- |
-- Wishbone handling -------------------------------------------------------- |
wbactive <= wb_stb_i and wb_cyc_i; |
|
wb_ack_o <= wbactive; |
|
wb_dat_o <= tcr0 when wbactive='1' and wb_adr_i(7 downto 0)=x"00" else |
std_logic_vector(compare0) when wbactive='1' and wb_adr_i(7 downto 0)=x"04" else |
std_logic_vector(counter0) when wbactive='1' and wb_adr_i(7 downto 0)=x"08" else |
tcr1 when wbactive='1' and wb_adr_i(7 downto 0)=x"0C" else |
std_logic_vector(compare1) when wbactive='1' and wb_adr_i(7 downto 0)=x"10" else |
std_logic_vector(counter1) when wbactive='1' and wb_adr_i(7 downto 0)=x"14" else |
(others => '-'); |
|
wb_irq0_o <= trig0 and irq0en; |
wb_irq1_o <= trig1 and irq1en; |
|
tcr0 <= "0000000000000000000000000000" & en0 & ar0 & irq0en & trig0; |
tcr1 <= "0000000000000000000000000000" & en1 & ar1 & irq1en & trig1; |
|
timerproc: process (reset, clk) is |
variable val : std_logic_vector(31 downto 0); |
begin |
if reset='1' then |
en0 <= '0'; -- enable |
en1 <= '0'; |
ar0 <= '0'; -- auto reload |
ar1 <= '0'; |
trig0 <= '0'; -- triggered |
trig1 <= '0'; |
irq0en <= '0'; -- IRQ enable |
irq1en <= '0'; |
compare0 <= TO_UNSIGNED(0, 32); -- compare |
compare1 <= TO_UNSIGNED(0, 32); |
counter0 <= TO_UNSIGNED(0, 32); -- actual counter |
counter1 <= TO_UNSIGNED(0, 32); |
elsif clk'event and clk='1' then |
|
-- Reset trigX on TCR access -------------------------------- |
if wbactive='1' and wb_adr_i(7 downto 0)=x"00" then |
trig0 <= '0'; |
end if; |
if wbactive='1' and wb_adr_i(7 downto 0)=x"0C" then |
trig1 <= '0'; |
end if; |
|
-- WB write register ---------------------------------------- |
if wbactive='1' and wb_we_i='1' then |
|
-- decode WB_SEL_I -- |
if wb_sel_i(3)='1' then |
val(31 downto 24) := wb_dat_i(31 downto 24); |
end if; |
if wb_sel_i(2)='1' then |
val(23 downto 16) := wb_dat_i(23 downto 16); |
end if; |
if wb_sel_i(1)='1' then |
val(15 downto 8) := wb_dat_i(15 downto 8); |
end if; |
if wb_sel_i(0)='1' then |
val( 7 downto 0) := wb_dat_i( 7 downto 0); |
end if; |
|
-- decode WB_ADR_I -- |
if wb_adr_i(7 downto 0)=x"00" then |
en0 <= val(3); |
ar0 <= val(2); |
irq0en <= val(1); |
elsif wb_adr_i(7 downto 0)=x"04" then |
compare0 <= unsigned(val); |
elsif wb_adr_i(7 downto 0)=x"08" then |
counter0 <= unsigned(val); |
elsif wb_adr_i(7 downto 0)=x"0C" then |
en1 <= val(3); |
ar1 <= val(2); |
irq1en <= val(1); |
elsif wb_adr_i(7 downto 0)=x"10" then |
compare1 <= unsigned(val); |
elsif wb_adr_i(7 downto 0)=x"14" then |
counter1 <= unsigned(val); |
end if; |
end if; |
|
|
-- timer0 --------------------------------------------------- |
if en0='1' then |
if counter0 = compare0 then |
trig0 <= '1'; |
if ar0='1' then |
counter0 <= to_unsigned(1, 32); |
else |
en0 <= '0'; |
end if; |
else |
counter0 <= counter0 + 1; |
end if; |
end if; |
|
-- timer1 --------------------------------------------------- |
if en1='1' then |
if counter1 = compare1 then |
trig1 <= '1'; |
if ar1='1' then |
counter1 <= to_unsigned(1, 32); |
else |
en1 <= '0'; |
end if; |
else |
counter1 <= counter1 + 1; |
end if; |
end if; |
|
end if; |
end process; |
|
end rtl; |
/ip/wb_sram/asram_core.v
0,0 → 1,325
// ============================================================================= |
// COPYRIGHT NOTICE |
// Copyright 2004 (c) Lattice Semiconductor Corporation |
// ALL RIGHTS RESERVED |
// This confidential and proprietary software may be used only as authorised by |
// a licensing agreement from Lattice Semiconductor Corporation. |
// The entire notice above must be reproduced on all authorized copies and |
// copies may only be made to the extent permitted by a licensing agreement from |
// Lattice Semiconductor Corporation. |
// |
// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) |
// 5555 NE Moore Court 408-826-6000 (other locations) |
// Hillsboro, OR 97124 web : http://www.latticesemi.com/ |
// U.S.A email: techsupport@latticesemi.com |
// =============================================================================/ |
// FILE DETAILS |
// Project : Async SRAM Controller |
// File : asram_core.v |
// Title : Asynchronous SRAM Controller |
// Dependencies : asram_params.v |
// Description : Implements the logic to interface async SRAM with Wishbone |
// bus. |
// ============================================================================= |
// REVISION HISTORY |
// Version : 1.0 |
// Author : Frank Xie |
// Mod. Date : Jun 27, 2005 |
// Changes Made : Initial Creation |
// |
// ============================================================================= |
`timescale 1ns/100ps |
|
module asram_core #(parameter SRAM_DATA_WIDTH = 32, |
parameter SRAM_ADDR_WIDTH = 18, |
parameter READ_LATENCY = 1, |
parameter WRITE_LATENCY = 1 |
) |
(// Clock and reset |
clk_i, |
rst_i, |
// Wishbone side interface |
cti_i, |
bte_i, |
addr_i, |
dat_i, |
sel_i, |
we_i, |
stb_i, |
cyc_i, |
ack_o, |
dat_o, |
// SRAM side interface |
sram_addr, |
sram_data_in, |
sram_data_out, |
sram_csn, |
sram_be, |
sram_wen, |
sram_oen); |
|
parameter SRAM_CYCLE = 32/SRAM_DATA_WIDTH; |
parameter SRAM_BE_WIDTH = SRAM_DATA_WIDTH/8; |
|
////////////////////////////////////////////////////////////////////////////// |
//clock and reset inputs |
input clk_i; |
input rst_i; |
//Wishbone side interface |
input [2:0] cti_i; |
input [1:0] bte_i; |
input [31:0] addr_i; |
input [31:0] dat_i; |
input [3:0] sel_i; |
input we_i; |
input stb_i; |
input cyc_i; |
output ack_o; |
output [31:0] dat_o; |
//SRAM side interface |
output [SRAM_ADDR_WIDTH-1:0] sram_addr; |
output sram_csn; |
output [SRAM_BE_WIDTH-1:0] sram_be; |
output sram_wen; |
output sram_oen; |
input [SRAM_DATA_WIDTH-1:0] sram_data_in; |
output [SRAM_DATA_WIDTH-1:0] sram_data_out; |
|
/////////////////////////////////////////////////////////////////////////// |
// Internal registers and wires |
reg [31:0] dat_o; |
reg [2:0] main_sm; |
reg ack_o; |
reg sram_wen; |
reg [3:0] read_latency_cnt; |
reg [3:0] write_latency_cnt; |
reg [2:0] cycle; |
wire sram_data_width_32 = (SRAM_DATA_WIDTH == 32 ? 1 : 0); |
wire sram_data_width_16 = (SRAM_DATA_WIDTH == 16 ? 1 : 0); |
wire sram_data_width_8 = (SRAM_DATA_WIDTH == 8 ? 1 : 0); |
wire [31:0] sram_addr_cls; |
reg [31:0] sram_addr_bst; |
reg we_bst,rd_bst ; |
|
wire burst_enabled = 1; |
|
`define IDLE 3'b000 |
`define READ1 3'b001 |
`define READ2 3'b010 |
`define READ3 3'b011 |
`define RD_BST 3'b100 |
`define WRITE1 3'b101 |
`define WRITE2 3'b110 |
`define WRITE3 3'b111 |
|
// Main State Machine which controls the WishBone and SRAM interface |
always @ (posedge rst_i or posedge clk_i) begin |
if (rst_i) begin |
main_sm <= `IDLE; |
read_latency_cnt <= READ_LATENCY; |
write_latency_cnt <= WRITE_LATENCY; |
dat_o <= 0; |
cycle <= 0; |
sram_wen <= 1'b1; |
ack_o <= 1'b0; |
we_bst <= 0; |
rd_bst <= 0; |
sram_addr_bst <= 0; |
end else begin |
case (main_sm) |
`IDLE: begin |
if (cyc_i && stb_i && ~ack_o) |
if (we_i) begin |
ack_o <= 1'b0; |
sram_wen <= 1'b0; |
write_latency_cnt <= WRITE_LATENCY; |
main_sm <= `WRITE1; |
rd_bst <= 0; |
// classic cycle or single cycle or data width < 32 |
if (cti_i == 3'b000 || cti_i == 3'b111 || !sram_data_width_32) begin |
we_bst <= 1'b0; |
sram_addr_bst <= 0; |
end else begin |
sram_addr_bst <= addr_i[SRAM_ADDR_WIDTH-1:0]; |
we_bst <= 1'b1; |
end |
// classic cycle or if data width < 32 |
end else if (cti_i == 3'b000 || cti_i == 3'b111 || !sram_data_width_32) begin |
we_bst <= 1'b0; |
rd_bst <= 0; |
sram_addr_bst <= 0; |
read_latency_cnt <= READ_LATENCY - 1; |
`ifdef NO_READ_WAIT |
main_sm <= `READ2; |
if (sram_data_width_32) |
ack_o <= 1'b1; |
else |
ack_o <= 1'b0; |
dat_o[SRAM_DATA_WIDTH - 1 : 0] <= sram_data_in; |
`else |
main_sm <= `READ1; |
ack_o <= 1'b0; |
`endif |
end else begin // burst read cycle |
main_sm <= `RD_BST; |
ack_o <= 1'b0; |
we_bst <= 1'b0; |
rd_bst <= 1'b1; |
sram_addr_bst<= addr_i[SRAM_ADDR_WIDTH-1:0]; |
read_latency_cnt <= READ_LATENCY - 1; |
end |
else begin |
main_sm <= `IDLE; |
sram_wen <= 1'b1; |
ack_o <= 1'b0; |
we_bst <= 1'b0; |
rd_bst <= 1'b0; |
end |
cycle <= SRAM_CYCLE; |
dat_o <= 0; |
end |
`READ1: if (read_latency_cnt != 4'b0000) |
read_latency_cnt <= read_latency_cnt - 1; |
else begin |
main_sm <= `READ2; |
ack_o <= (cycle == 1) ? 1'b1 : 1'b0; |
if (sram_data_width_32) |
dat_o <= sram_data_in; |
if (sram_data_width_16) begin |
if (cycle == 1) dat_o[31:16] <= sram_data_in; |
else dat_o[15:0] <= sram_data_in; |
end |
if (sram_data_width_8) begin |
if (cycle == 4) dat_o[7:0] <= sram_data_in; |
else if (cycle == 3) dat_o[15:8] <= sram_data_in; |
else if (cycle == 2) dat_o[23:16] <= sram_data_in; |
else dat_o[31:24] <= sram_data_in; |
end |
end |
`READ2: begin |
ack_o <= 1'b0; |
main_sm <= `READ3; |
read_latency_cnt <= READ_LATENCY; |
if (cycle == 1) |
cycle <= SRAM_CYCLE; |
else |
cycle <= cycle - 1; end |
`READ3: begin |
if (cycle != SRAM_CYCLE) begin |
`ifdef NO_READ_WAIT |
if (sram_data_width_32) |
dat_o <= sram_data_in; |
if (sram_data_width_16) begin |
if (cycle == 1) dat_o[31:16] <= sram_data_in; |
else dat_o[15:0] <= sram_data_in; |
end |
if (sram_data_width_8) begin |
if (cycle == 3) dat_o[15:8] <= sram_data_in; |
else if (cycle == 2) dat_o[23:16] <= sram_data_in; |
else if (cycle == 1) dat_o[31:24] <= sram_data_in; |
end |
ack_o <= (cycle == 1) ? 1'b1 : 1'b0; |
main_sm <= `READ2; |
`else |
main_sm <= `READ1; |
ack_o <= 1'b0; |
`endif |
end |
else if (cyc_i & stb_i) begin |
read_latency_cnt <= READ_LATENCY; |
`ifdef NO_READ_WAIT |
main_sm <= `READ2; |
if (SRAM_DATA_WIDTH == 32) |
ack_o <= 1'b1; |
else |
ack_o <= 1'b0; |
dat_o[SRAM_DATA_WIDTH - 1 : 0] <= sram_data_in; |
`else |
main_sm <= `READ1; |
ack_o <= 1'b0; |
`endif |
cycle <= SRAM_CYCLE; |
end else begin |
main_sm <= `IDLE; |
ack_o <= 1'b0; |
end |
end |
`RD_BST: begin |
if (read_latency_cnt == 0) begin |
dat_o <= sram_data_in; |
ack_o <= 1'b1; |
sram_addr_bst <= sram_addr_bst + 4; // always four because 32 bit array |
if (cti_i == 3'b111) begin |
main_sm <= `IDLE; |
end else begin |
read_latency_cnt <= READ_LATENCY - 1; |
main_sm <= `RD_BST; |
end |
end else begin |
ack_o <= 1'b0; |
read_latency_cnt <= read_latency_cnt - 1; |
main_sm <= `RD_BST; |
end |
end |
`WRITE1: begin |
if (write_latency_cnt == 0) begin |
ack_o <= (cycle == 1) ? 1'b1 : 1'b0; |
main_sm <= `WRITE2; |
sram_addr_bst <= sram_addr_bst + 4; // always four because 32 bit array |
if (we_bst) begin |
if (cti_i == 3'b111) begin |
sram_wen <= 1'b1; |
we_bst <= 0; |
end |
end else begin |
sram_wen <= 1'b1; |
end |
end else begin |
ack_o <= 1'b0; |
sram_wen <= 1'b0; |
write_latency_cnt <= write_latency_cnt - 1; |
end |
end |
`WRITE2: begin |
ack_o <= 1'b0; |
if (cycle != 1) begin |
cycle <= cycle - 1; |
main_sm <= `WRITE1; |
write_latency_cnt <= WRITE_LATENCY + 1; |
end else begin |
cycle <= SRAM_CYCLE; |
main_sm <= `IDLE; |
end |
end |
endcase |
end |
end |
|
assign sram_addr_cls = (cyc_i && (SRAM_CYCLE == 1)) ? {addr_i[31:2],2'b00} : |
(cyc_i && (SRAM_CYCLE == 2) && (cycle == 2)) ? {addr_i[31:2],2'b00} : |
(cyc_i && (SRAM_CYCLE == 2) && (cycle == 1)) ? {addr_i[31:2],2'b10} : |
(cyc_i && (SRAM_CYCLE == 4) && (cycle == 4)) ? {addr_i[31:2],2'b00} : |
(cyc_i && (SRAM_CYCLE == 4) && (cycle == 3)) ? {addr_i[31:2],2'b01} : |
(cyc_i && (SRAM_CYCLE == 4) && (cycle == 2)) ? {addr_i[31:2],2'b10} : |
(cyc_i && (SRAM_CYCLE == 4) && (cycle == 1)) ? {addr_i[31:2],2'b11} : |
0; |
assign sram_addr = ((rd_bst | we_bst) ? sram_addr_bst : sram_addr_cls); |
|
assign sram_oen = ~(stb_i && cyc_i && ~we_i); |
assign sram_csn = ~(stb_i && cyc_i); |
assign sram_be = ((SRAM_CYCLE == 1)) ? ~sel_i : |
((SRAM_CYCLE == 2) && (cycle == 2)) ? ~sel_i[1:0] : |
((SRAM_CYCLE == 2) && (cycle == 1)) ? ~sel_i[3:2] : |
((SRAM_CYCLE == 4) && (cycle == 4)) ? ~sel_i[0] : |
((SRAM_CYCLE == 4) && (cycle == 3)) ? ~sel_i[1] : |
((SRAM_CYCLE == 4) && (cycle == 2)) ? ~sel_i[2] : |
((SRAM_CYCLE == 4) && (cycle == 1)) ? ~sel_i[3] : {4'b111}; |
|
assign sram_data_out = (sram_data_width_32 ? dat_i : |
(sram_data_width_16 ? ((cycle == 2) ? dat_i[15:0] : dat_i[31:16]) : |
((cycle == 4) ? dat_i[7:0] : |
(cycle == 3) ? dat_i[15:8] : |
(cycle == 2) ? dat_i[23:16] : |
(cycle == 1) ? dat_i[31:24] : 0))); |
|
endmodule |
/ip/wb_sram/asram_top.v
0,0 → 1,182
// ============================================================================= |
// COPYRIGHT NOTICE |
// Copyright 2004 (c) Lattice Semiconductor Corporation |
// ALL RIGHTS RESERVED |
// This confidential and proprietary software may be used only as authorised by |
// a licensing agreement from Lattice Semiconductor Corporation. |
// The entire notice above must be reproduced on all authorized copies and |
// copies may only be made to the extent permitted by a licensing agreement from |
// Lattice Semiconductor Corporation. |
// |
// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) |
// 5555 NE Moore Court 408-826-6000 (other locations) |
// Hillsboro, OR 97124 web : http://www.latticesemi.com/ |
// U.S.A email: techsupport@latticesemi.com |
// =============================================================================/ |
// FILE DETAILS |
// Project : Async SRAM Controller |
// File : asram_core.v |
// Title : Asynchronous SRAM Controller |
// Dependencies : asram_params.v |
// Description : Implements the logic to interface async SRAM with Wishbone |
// bus. |
// ============================================================================= |
// REVISION HISTORY |
// Version : 1.0 |
// Author : Frank Xie |
// Mod. Date : Jun 27, 2005 |
// Changes Made : Initial Creation |
// |
// ============================================================================= |
`timescale 1ns/100ps |
|
|
module asram_top |
#(parameter SRAM_DATA_WIDTH = 16, |
parameter SRAM_ADDR_WIDTH = 18, |
parameter READ_LATENCY = 1, |
parameter WRITE_LATENCY = 1, |
parameter FLASH_SIGNALS = 0, |
parameter FLASH_BYTE = 0, |
parameter FLASH_WP = 0, |
parameter FLASH_RST = 0, |
parameter FLASH_BYTEN = 0, |
parameter FLASH_WPN = 0, |
parameter FLASH_RSTN = 0) |
( |
// Clock and reset |
clk_i, |
rst_i, |
// Wishbone side interface |
ASRAM_CTI_I, |
ASRAM_BTE_I, |
ASRAM_ADR_I, |
ASRAM_DAT_I, |
ASRAM_SEL_I, |
ASRAM_WE_I, |
ASRAM_STB_I, |
ASRAM_CYC_I, |
ASRAM_LOCK_I, |
ASRAM_ACK_O, |
ASRAM_DAT_O, |
ASRAM_ERR_O, |
ASRAM_RTY_O, |
// SRAM side interface |
sram_addr, |
sram_data_in, |
sram_data_out, |
sram_csn, |
sram_be, |
sram_wen, |
sram_oen, |
sram_byten, |
sram_wpn, |
sram_rstn); |
|
`define DLY 0 |
parameter SRAM_BE_WIDTH = SRAM_DATA_WIDTH/8; |
|
////////////////////////////////////////////////////////////////////////////// |
//clock and reset inputs |
input clk_i; |
input rst_i; |
//Wishbone side interface |
input [2:0] ASRAM_CTI_I; |
input [1:0] ASRAM_BTE_I; |
input [31:0] ASRAM_ADR_I; |
input [31:0] ASRAM_DAT_I; |
input [3:0] ASRAM_SEL_I; |
input ASRAM_WE_I; |
input ASRAM_STB_I; |
input ASRAM_CYC_I; |
input ASRAM_LOCK_I; |
output ASRAM_ACK_O; |
output [31:0] ASRAM_DAT_O; |
output ASRAM_ERR_O; |
wire ASRAM_ERR_O = 1'b0; |
output ASRAM_RTY_O; |
wire ASRAM_RTY_O = 1'b0; |
|
//SRAM side interface |
output [SRAM_ADDR_WIDTH-1:0] sram_addr; |
output sram_csn; |
output [SRAM_BE_WIDTH-1:0] sram_be; |
output sram_wen; |
output sram_oen; |
output [SRAM_DATA_WIDTH-1:0] sram_data_out; |
input [SRAM_DATA_WIDTH-1:0] sram_data_in; |
|
// These are extra for flash |
output sram_byten; |
wire sram_byten ; |
output sram_wpn; |
wire sram_wpn ; |
output sram_rstn; |
wire sram_rstn ; |
|
generate |
if (FLASH_BYTEN == 1) |
assign sram_byten = 1'b1; |
else |
assign sram_byten = 1'b0; |
endgenerate |
generate |
if (FLASH_WPN == 1) |
assign sram_wpn = 1'b1; |
else |
assign sram_wpn = 1'b0; |
endgenerate |
generate |
if (FLASH_RSTN == 1) |
assign sram_rstn = 1'b1; |
else |
assign sram_rstn = 1'b0; |
endgenerate |
|
wire [SRAM_ADDR_WIDTH-1:0] sram_addr_core; |
wire sram_csn_core; |
wire [SRAM_BE_WIDTH-1:0] sram_be_core; |
wire sram_wen_core; |
wire sram_oen_core; |
wire [SRAM_DATA_WIDTH-1:0] sram_data_out; |
|
asram_core #(.SRAM_DATA_WIDTH (SRAM_DATA_WIDTH), |
.SRAM_ADDR_WIDTH (SRAM_ADDR_WIDTH), |
.READ_LATENCY (READ_LATENCY), |
.WRITE_LATENCY (WRITE_LATENCY)) |
core_inst (.clk_i(clk_i), |
.rst_i(rst_i), |
.cti_i(ASRAM_CTI_I), |
.bte_i(ASRAM_BTE_I), |
.addr_i(ASRAM_ADR_I), |
.dat_i(ASRAM_DAT_I), |
.sel_i(ASRAM_SEL_I), |
.we_i(ASRAM_WE_I), |
.stb_i(ASRAM_STB_I), |
.cyc_i(ASRAM_CYC_I), |
.ack_o(ASRAM_ACK_O), |
.dat_o(ASRAM_DAT_O), |
.sram_addr(sram_addr_core), |
.sram_data_in(sram_data_in), |
.sram_data_out(sram_data_out), |
.sram_csn(sram_csn_core), |
.sram_be(sram_be_core), |
.sram_wen(sram_wen_core), |
.sram_oen(sram_oen_core)); |
|
wire [SRAM_DATA_WIDTH-1: 0] zwire; |
generate |
genvar i; |
for ( i = 0 ; i < SRAM_DATA_WIDTH; i = i + 1) |
begin : zwa |
assign zwire[i] = 1'bz; |
end |
endgenerate |
|
assign #`DLY sram_addr = sram_addr_core; |
assign #`DLY sram_csn = sram_csn_core; |
assign #`DLY sram_be = sram_be_core; |
assign #`DLY sram_wen = sram_wen_core; |
assign #`DLY sram_oen = sram_oen_core; |
|
endmodule |