M1: spi_transmitter architecture
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="DSABoardId" Val="zybo-z7-20"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="3"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
|
||||
@@ -29,16 +29,17 @@ begin
|
||||
|
||||
SPI_Transmitter_Inst: entity work.spi_transmitter
|
||||
generic map (
|
||||
AW => AW
|
||||
AW => AW,
|
||||
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,
|
||||
data => data,
|
||||
addr => addr,
|
||||
mosi => mosi,
|
||||
sck => sck,
|
||||
ssel => ssel
|
||||
);
|
||||
|
||||
Rom_Inst: entity work.spi2display_rom
|
||||
|
||||
@@ -7,14 +7,14 @@ end;
|
||||
|
||||
|
||||
architecture rtl of spi2display_tb is
|
||||
|
||||
|
||||
constant EXT_CLOCK_FREQ : integer := 125000000;
|
||||
constant SCK_FREQ : integer := 1000000;
|
||||
constant CPOL : std_logic := '0';
|
||||
constant CPHA : std_logic := '0';
|
||||
|
||||
constant clk_half_period : time := 1 sec / EXT_CLOCK_FREQ / 2;
|
||||
|
||||
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '1';
|
||||
|
||||
@@ -25,11 +25,11 @@ begin
|
||||
end process;
|
||||
|
||||
reset <= '0' after 100 * clk_half_period;
|
||||
|
||||
|
||||
dut: entity work.spi2display
|
||||
generic map (
|
||||
CPOL => CPOL,
|
||||
CPHA => CPHA,
|
||||
-- CPOL => CPOL,
|
||||
-- CPHA => CPHA,
|
||||
CLOCK_FREQ => EXT_CLOCK_FREQ,
|
||||
SCK_FREQ => SCK_FREQ
|
||||
)
|
||||
@@ -40,5 +40,5 @@ begin
|
||||
sck => open,
|
||||
ssel => open
|
||||
);
|
||||
|
||||
|
||||
end;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity spi_transmitter is
|
||||
generic(
|
||||
@@ -22,7 +23,206 @@ end;
|
||||
|
||||
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 RegDataLd : std_logic := '0';
|
||||
signal RegDataShift : std_logic := '0';
|
||||
signal CntBitsEn : std_logic := '0';
|
||||
signal CntBitsTC : std_logic := '0';
|
||||
signal CtrlBits : std_logic_vector(1 downto 0) := "00";
|
||||
|
||||
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' or cntVal = 0 then
|
||||
cntVal := to_unsigned(7, 3);
|
||||
CntBitsTC <= '0';
|
||||
elsif CntBitsEn = '1' then
|
||||
cntVal := cntVal - 1;
|
||||
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;
|
||||
begin
|
||||
-- Kontrollbits
|
||||
CtrlBits <= data(9 downto 8);
|
||||
|
||||
-- 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 <= '0';
|
||||
RegDataShift <= '0';
|
||||
cntAddrEn <= '0';
|
||||
CntBitsEn <= '0';
|
||||
|
||||
-- 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 <= '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;
|
||||
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;
|
||||
RegDataLd <= '1';
|
||||
CntBitsEn <= '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 <= '1';
|
||||
elsif CtrlBits = "11" or CtrlBits = "01" then
|
||||
state_next <= S_START;
|
||||
cntAddrRst <= '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 <= 'X';
|
||||
RegDataShift <= 'X';
|
||||
cntAddrEn <= 'X';
|
||||
end if;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Register fuer Zustand und Moore-Ausgaenge
|
||||
Reg: process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
state <= state_next;
|
||||
-- Berechnung der Moore-Ausgaenge
|
||||
-- Default-Werte
|
||||
ssel <= 'X';
|
||||
sck <= 'X';
|
||||
|
||||
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;
|
||||
end rtl;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# work-Bibliothek erzeugen, falls nicht schon vorhanden
|
||||
if { [file exists work] == 0} {
|
||||
vlib work
|
||||
}
|
||||
|
||||
# Benoetigte Dateien uebersetzen
|
||||
vcom -work work spi_transmitter.vhd
|
||||
vcom -work work spi2display_rom.vhd
|
||||
vcom -work work spi2display.vhd
|
||||
vcom -work work spi2display_tb.vhd
|
||||
|
||||
# Simulator starten
|
||||
vsim -voptargs=+acc spi2display_tb
|
||||
|
||||
# Breite der Namensspalte
|
||||
configure wave -namecolwidth 128
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -namecolwidth 154
|
||||
configure wave -valuecolwidth 100
|
||||
set NumericStdNoWarnings 1
|
||||
|
||||
if {1} {
|
||||
add wave -divider "Externe Signale - spi2display"
|
||||
add wave -noupdate /spi2display_tb/dut/clk
|
||||
add wave -noupdate /spi2display_tb/dut/reset
|
||||
add wave -noupdate /spi2display_tb/dut/sck
|
||||
add wave -noupdate /spi2display_tb/dut/mosi
|
||||
add wave -noupdate /spi2display_tb/dut/ssel
|
||||
}
|
||||
|
||||
if {1} {
|
||||
add wave -divider "Interne Signale"
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/data
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/addr
|
||||
add wave -divider "Steuerwerk"
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/Steuerwerk/state
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/Steuerwerk/state_next
|
||||
add wave -divider "Steuersignale"
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/CntSckTc
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/CntBitsTC
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/CtrlBits
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/cntAddrEn
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/cntAddrRst
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/RegDataLd
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/RegDataShift
|
||||
add wave -noupdate /spi2display_tb/dut/SPI_Transmitter_Inst/CntBitsEn
|
||||
}
|
||||
|
||||
run 100 us
|
||||
Reference in New Issue
Block a user