M1: Blockschaltbilder und spi_transmitter
This commit is contained in:
Binary file not shown.
@@ -20,10 +20,14 @@ end;
|
||||
|
||||
architecture rtl of spi2display is
|
||||
|
||||
constant AW : POSITIVE := 8;
|
||||
constant AW : POSITIVE := 8;
|
||||
|
||||
signal addr : std_logic_vector(AW-1 downto 0);
|
||||
signal data : std_logic_vector(9 downto 0);
|
||||
signal addr : std_logic_vector(AW-1 downto 0);
|
||||
signal data_rom : std_logic_vector(9 downto 0);
|
||||
|
||||
signal data : std_logic_vector(7 downto 0);
|
||||
signal valid : std_logic;
|
||||
signal ready : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@@ -33,13 +37,16 @@ begin
|
||||
CLKDIV => CLOCK_FREQ / (SCK_FREQ * 4)
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
data => data,
|
||||
addr => addr,
|
||||
mosi => mosi,
|
||||
sck => sck,
|
||||
ssel => ssel
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
|
||||
s_data => data,
|
||||
s_valid => valid,
|
||||
s_ready => ready,
|
||||
|
||||
mosi => mosi,
|
||||
sck => sck,
|
||||
ssel => ssel
|
||||
);
|
||||
|
||||
Rom_Inst: entity work.spi2display_rom
|
||||
@@ -52,4 +59,17 @@ begin
|
||||
dout => data
|
||||
);
|
||||
|
||||
Control_Inst: entity work.spi_rom_control
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
|
||||
addr => addr,
|
||||
din => data_rom,
|
||||
|
||||
m_data => data,
|
||||
m_valid => valid,
|
||||
m_ready => ready
|
||||
)
|
||||
|
||||
end rtl;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity spi_rom_control is
|
||||
port (
|
||||
-- control io
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- Interface rom
|
||||
addr : out std_logic_vector(7 downto 0);
|
||||
din : in std_logic_vector(9 downto 0);
|
||||
|
||||
-- Streaming Interface spi_transmitter
|
||||
m_data : out std_logic_vector(7 downto 0);
|
||||
m_valid : out std_logic;
|
||||
m_ready : in std_logic;
|
||||
);
|
||||
end entity;
|
||||
|
||||
|
||||
architecture rtl of spi_rom_control is
|
||||
|
||||
begin
|
||||
|
||||
|
||||
|
||||
end architecture;
|
||||
@@ -9,245 +9,205 @@ entity spi_transmitter is
|
||||
AW : positive := 8;
|
||||
CLKDIV : positive := 100000/4
|
||||
);
|
||||
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic := '1';
|
||||
data : in std_logic_vector ( 9 downto 0);
|
||||
addr : out std_logic_vector (AW-1 downto 0);
|
||||
|
||||
s_data : in std_logic_vector (7 downto 0);
|
||||
s_valid : in std_logic;
|
||||
s_ready : out std_logic;
|
||||
|
||||
mosi : out std_logic:='1';
|
||||
sck : out std_logic:='1';
|
||||
ssel : out std_logic:='1'
|
||||
);
|
||||
end;
|
||||
);
|
||||
end;
|
||||
|
||||
architecture rtl of spi_transmitter is
|
||||
architecture rtl of spi_transmitter is
|
||||
|
||||
-- Steuersignale zwischen Steuerwerk und Rechenwerk
|
||||
signal cntAddrRst : std_logic := '0';
|
||||
signal cntAddrEn : std_logic := '0';
|
||||
signal CntSckTc : std_logic := '0';
|
||||
signal CntSckRst : std_logic := '0';
|
||||
signal RegDataLd : std_logic := '0';
|
||||
signal RegDataShift : std_logic := '0';
|
||||
signal RegDataEn : std_logic := '0';
|
||||
signal CntBitsEn : std_logic := '0';
|
||||
signal CntBitsTC : std_logic := '0';
|
||||
signal CtrlBits : std_logic_vector(1 downto 0) := "00";
|
||||
signal CntBitsRst : std_logic := '0';
|
||||
|
||||
-- Finite state machine
|
||||
type state_t is (S_IDLE, S_STEP_1, S_STEP_2, S_STEP_3, S_STEP_4, S_ERROR);
|
||||
signal state : state_t := S_IDLE;
|
||||
signal state_next : state_t;
|
||||
|
||||
begin
|
||||
|
||||
Rechenwerk : block
|
||||
begin
|
||||
-- Zaehler fuer Adresse
|
||||
CntAddr: process
|
||||
variable cntVal : unsigned(AW-1 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if reset = '1' or CntAddrRst = '1' then
|
||||
cntVal := (others=>'0');
|
||||
elsif cntAddrEn = '1' then
|
||||
cntVal := cntVal + 1;
|
||||
end if;
|
||||
|
||||
addr <= std_logic_vector(cntVal);
|
||||
end process;
|
||||
|
||||
-- Zaehler fuer SPI-Takt SCK
|
||||
CntSck: process
|
||||
variable cntVal : unsigned(31 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if reset = '1' or cntVal = 0 then
|
||||
cntVal := to_unsigned(CLKDIV-1, 32);
|
||||
else
|
||||
cntVal := cntVal - 1;
|
||||
end if;
|
||||
|
||||
if cntVal = 0 then
|
||||
CntSckTc <= '1';
|
||||
else
|
||||
CntSckTc <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Zaheler fuer zu sendende Bits
|
||||
CntBits: process
|
||||
variable cntVal : unsigned(2 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if reset = '1' then
|
||||
cntVal := to_unsigned(0, 3);
|
||||
elsif CntBitsEn = '1' then
|
||||
if cntVal = 0 then
|
||||
cntVal := to_unsigned(7, 3);
|
||||
else
|
||||
cntVal := cntVal - 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if cntVal = 0 then
|
||||
CntBitsTC <= '1';
|
||||
else
|
||||
CntBitsTC <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Schieberegister Daten
|
||||
RegData: process
|
||||
variable Q : std_logic_vector(7 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if RegDataLd = '1' then
|
||||
Q := data(7 downto 0);
|
||||
elsif RegDataShift = '1' then
|
||||
Q := Q(6 downto 0) & '0';
|
||||
end if;
|
||||
mosi <= Q(7);
|
||||
end process;
|
||||
end block;
|
||||
|
||||
Steuerwerk : block
|
||||
-- Typ fuer die Zustandswerte
|
||||
type state_t is (S_START, S_STEP_1, S_STEP_2, S_STEP_3, S_STEP_4, S_DEAD_END, S_ERROR);
|
||||
-- Interne Signale fuer Rechenwerk
|
||||
signal state : state_t := S_START;
|
||||
signal state_next : state_t;
|
||||
-- Interne Signale fuer "Mealy"- Ausgaenge
|
||||
signal RegDataLd_next : std_logic := '0';
|
||||
signal RegDataShift_next : std_logic := '0';
|
||||
signal cntAddrEn_next : std_logic := '0';
|
||||
signal CntBitsEn_next : std_logic := '0';
|
||||
signal cntAddrRst_next : std_logic := '0';
|
||||
|
||||
-- Zaehler fuer SPI-Takt SCK
|
||||
CntSck: process
|
||||
variable cntVal : unsigned(31 downto 0) := (others=>'0');
|
||||
begin
|
||||
-- Kontrollbits
|
||||
CtrlBits <= data(9 downto 8);
|
||||
wait until rising_edge(clk);
|
||||
if CntSckRst = '1' or cntVal = 0 then
|
||||
cntVal := to_unsigned(CLKDIV-1, 32);
|
||||
else
|
||||
cntVal := cntVal - 1;
|
||||
end if;
|
||||
|
||||
-- Prozess zur Berechnung des Folgezustandes und der Mealy-Ausgaenge
|
||||
Transition: process(Reset, CntSckTc, CntBitsTC, CtrlBits)
|
||||
begin
|
||||
-- Default-Werte fuer Folgezustand und Mealy-Ausgaenge
|
||||
state_next <= S_ERROR;
|
||||
RegDataLd_next <= '0';
|
||||
RegDataShift_next <= '0';
|
||||
cntAddrEn_next <= '0';
|
||||
CntBitsEn_next <= '0';
|
||||
cntAddrRst_next <= '0';
|
||||
if cntVal = 0 then
|
||||
CntSckTc <= '1';
|
||||
else
|
||||
CntSckTc <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Berechnung des Folgezustandes und der Mealy-Ausgaenge
|
||||
case state is
|
||||
when S_START =>
|
||||
If reset = '1' then
|
||||
state_next <= S_START;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_1;
|
||||
RegDataLd_next <= '1';
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_START;
|
||||
end if;
|
||||
when S_STEP_1 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_START;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_2;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_1;
|
||||
end if;
|
||||
when S_STEP_2 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_START;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_3;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_2;
|
||||
end if;
|
||||
when S_STEP_3 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_START;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_4;
|
||||
CntBitsEn_next <= '1';
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_3;
|
||||
end if;
|
||||
when S_STEP_4 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_START;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_4;
|
||||
elsif CntSckTc = '1' and CntBitsTC = '0' then
|
||||
state_next <= S_STEP_1;
|
||||
RegDataShift_next <= '1';
|
||||
elsif CntSckTc = '1' and CntBitsTC = '1' then
|
||||
if CtrlBits = "10" then
|
||||
state_next <= S_DEAD_END;
|
||||
elsif CtrlBits = "00" then
|
||||
state_next <= S_START;
|
||||
cntAddrEn_next <= '1';
|
||||
elsif CtrlBits = "11" or CtrlBits = "01" then
|
||||
state_next <= S_START;
|
||||
cntAddrRst_next <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when S_DEAD_END =>
|
||||
if reset = '1' then
|
||||
state_next <= S_START;
|
||||
else
|
||||
state_next <= S_DEAD_END;
|
||||
end if;
|
||||
when S_ERROR =>
|
||||
if reset = '1' then
|
||||
state_next <= S_START;
|
||||
else
|
||||
state_next <= S_ERROR;
|
||||
RegDataLd_next <= 'X';
|
||||
RegDataShift_next <= 'X';
|
||||
cntAddrEn_next <= 'X';
|
||||
end if;
|
||||
end case;
|
||||
end process;
|
||||
-- Zaheler fuer zu sendende Bits
|
||||
CntBits: process
|
||||
variable cntVal : unsigned(2 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if CntBitsRst = '1' then
|
||||
cntVal := to_unsigned(0, 3);
|
||||
elsif CntBitsEn = '1' then
|
||||
cntVal := cntVal - 1;
|
||||
end if;
|
||||
|
||||
-- Register fuer Zustand und Ausgaenge
|
||||
Reg: process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if cntVal = 0 then
|
||||
CntBitsTC <= '1';
|
||||
else
|
||||
CntBitsTC <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Zustandswechsel
|
||||
state <= state_next;
|
||||
-- Ausgeange, welche abhaengig von Zustand und Eingaengen sind
|
||||
RegDataLd <= RegDataLd_next;
|
||||
RegDataShift <= RegDataShift_next;
|
||||
cntAddrEn <= cntAddrEn_next;
|
||||
CntBitsEn <= CntBitsEn_next;
|
||||
cntAddrRst <= cntAddrRst_next;
|
||||
-- Schieberegister Daten
|
||||
RegData: process
|
||||
variable Q : std_logic_vector(7 downto 0) := (others=>'0');
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if RegDataLd = '1' then
|
||||
Q := data; -- laden
|
||||
elsif RegDataEn = '1' then
|
||||
Q := Q(6 downto 0) & '0'; -- linksschieben
|
||||
end if;
|
||||
mosi <= Q(7);
|
||||
end process;
|
||||
|
||||
-- Berechnung der Moore-Ausgaenge, die nur vom Zustand abhaengen
|
||||
-- Default-Werte
|
||||
ssel <= 'X';
|
||||
sck <= 'X';
|
||||
-- Prozesse fuer endlichen Automaten
|
||||
Transition: process(reset, CntSckTc, CntBitsTC, s_valid)
|
||||
begin
|
||||
-- Default-Werte fuer Folgezustand und Mealy-Ausgaenge
|
||||
state_next <= S_ERROR;
|
||||
CntSckRst <= '0';
|
||||
RegDataLd <= '0';
|
||||
RegDataEn <= '0';
|
||||
CntBitsEn <= '0';
|
||||
CntBitsRst <= '0';
|
||||
|
||||
case state_next is
|
||||
when S_START =>
|
||||
ssel <= '1';
|
||||
sck <= '0';
|
||||
when S_STEP_1 =>
|
||||
ssel <= '0';
|
||||
sck <= '0';
|
||||
when S_STEP_2 =>
|
||||
ssel <= '0';
|
||||
sck <= '1';
|
||||
when S_STEP_3 =>
|
||||
ssel <= '0';
|
||||
sck <= '1';
|
||||
when S_STEP_4 =>
|
||||
ssel <= '0';
|
||||
sck <= '0';
|
||||
when S_DEAD_END =>
|
||||
ssel <= '1';
|
||||
sck <= '0';
|
||||
when S_ERROR =>
|
||||
ssel <= 'X';
|
||||
sck <= 'X';
|
||||
end case;
|
||||
end process;
|
||||
end block;
|
||||
-- Berechnung des Folgezustandes und der Mealy-Ausgaenge
|
||||
case state is
|
||||
when S_IDLE =>
|
||||
If reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
elsif s_valid = '1' then
|
||||
state_next <= S_STEP_1;
|
||||
RegDataLd <= '1';
|
||||
CntBitsRst <= '1';
|
||||
CntSckRst <= '1';
|
||||
elsif s_valid = '0' then
|
||||
state_next <= S_IDLE;
|
||||
end if;
|
||||
when S_STEP_1 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_2;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_1;
|
||||
end if;
|
||||
when S_STEP_2 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_3;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_2;
|
||||
end if;
|
||||
when S_STEP_3 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
elsif CntSckTc = '1' then
|
||||
state_next <= S_STEP_4;
|
||||
CntBitsEn <= '1';
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_3;
|
||||
end if;
|
||||
when S_STEP_4 =>
|
||||
If reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
elsif CntSckTc = '0' then
|
||||
state_next <= S_STEP_4;
|
||||
elsif CntSckTc = '1' and CntBitsTC = '0' then
|
||||
state_next <= S_STEP_1;
|
||||
RegDataEn <= '1';
|
||||
CntBitsEn <= '1';
|
||||
elsif CntSckTc = '1' and CntBitsTC = '1' then
|
||||
state_next <= S_IDLE;
|
||||
end if;
|
||||
when S_ERROR =>
|
||||
if reset = '1' then
|
||||
state_next <= S_IDLE;
|
||||
else
|
||||
state_next <= S_ERROR;
|
||||
CntSckRst <= 'X';
|
||||
RegDataLd <= 'X';
|
||||
RegDataEn <= 'X';
|
||||
CntBitsEn <= 'X';
|
||||
CntBitsRst <= 'X';
|
||||
end if;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Register fuer Zustand und Ausgaenge
|
||||
Reg: process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- Zustandswechsel
|
||||
state <= state_next;
|
||||
|
||||
-- Berechnung der Moore-Ausgaenge, die nur vom Zustand abhaengen
|
||||
-- Default-Werte
|
||||
ssel <= 'X';
|
||||
sck <= 'X';
|
||||
s_ready <= 'X';
|
||||
|
||||
case state_next is
|
||||
when S_IDLE =>
|
||||
ssel <= '1';
|
||||
sck <= '0';
|
||||
s_ready <= '1';
|
||||
when S_STEP_1 =>
|
||||
ssel <= '0';
|
||||
sck <= '0';
|
||||
s_ready <= '0';
|
||||
when S_STEP_2 =>
|
||||
ssel <= '0';
|
||||
sck <= '1';
|
||||
s_ready <= '0';
|
||||
when S_STEP_3 =>
|
||||
ssel <= '0';
|
||||
sck <= '1';
|
||||
s_ready <= '0';
|
||||
when S_STEP_4 =>
|
||||
ssel <= '0';
|
||||
sck <= '0';
|
||||
s_ready <= '0';
|
||||
when S_DEAD_END =>
|
||||
ssel <= '1';
|
||||
sck <= '0';
|
||||
s_ready <= '0';
|
||||
when S_ERROR =>
|
||||
ssel <= 'X';
|
||||
sck <= 'X';
|
||||
s_ready <= 'X';
|
||||
end case;
|
||||
end process;
|
||||
end rtl;
|
||||
|
||||
Reference in New Issue
Block a user