Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Platform-independent core collection
Manage
Activity
Members
Labels
Plan
Issues
15
Issue boards
Milestones
Wiki
Code
Merge requests
5
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
Platform-independent core collection
Commits
34bfc003
Commit
34bfc003
authored
6 years ago
by
Tomasz Wlostowski
Committed by
Tomasz Wlostowski
5 years ago
Browse files
Options
Downloads
Patches
Plain Diff
common: added a simple non-WB SPI master
parent
49d90649
Branches
tom-feb01
Branches containing commit
2 merge requests
!9
AFCZ-related fixes (SPI, etc)
,
!8
Fine Pulse Generator for sis83k/eRTM
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
modules/common/Manifest.py
+1
-0
1 addition, 0 deletions
modules/common/Manifest.py
modules/common/gc_simple_spi_master.vhd
+205
-0
205 additions, 0 deletions
modules/common/gc_simple_spi_master.vhd
with
206 additions
and
0 deletions
modules/common/Manifest.py
+
1
−
0
View file @
34bfc003
...
...
@@ -37,4 +37,5 @@ files = [
"
gc_async_counter_diff.vhd
"
,
"
gc_sync_word_wr.vhd
"
,
"
gc_sync_word_rd.vhd
"
,
"
gc_simple_spi_master.vhd
"
];
This diff is collapsed.
Click to expand it.
modules/common/gc_simple_spi_master.vhd
0 → 100644
+
205
−
0
View file @
34bfc003
-----------------------------------------------------------------------------
-- Title : SPI Bus Master
-- Project : Simple VME64x FMC Carrier (SVEC)
-------------------------------------------------------------------------------
-- File : gc_simple_spi_master.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-24
-- Last update: 2013-01-25
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Just a simple SPI master (bus-less).
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011-2013 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
entity
gc_simple_spi_master
is
generic
(
-- clock division ratio (SCLK = clk_sys_i / (2 ** g_div_ratio_log2).
g_div_ratio_log2
:
integer
:
=
2
;
-- number of data bits per transfer
g_num_data_bits
:
integer
:
=
2
);
port
(
clk_sys_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
-- state of the Chip select line (1 = CS active). External control
-- allows for multi-transfer commands (SPI master itself does not
-- control the state of spi_cs_n_o)
cs_i
:
in
std_logic
;
-- 1: start next transfer (using CPOL, DATA and SEL from the inputs below)
start_i
:
in
std_logic
;
-- Clock polarity: 1: slave clocks in the data on rising SCLK edge, 0: ...
-- on falling SCLK edge
cpol_i
:
in
std_logic
;
-- TX Data input
data_i
:
in
std_logic_vector
(
g_num_data_bits
-
1
downto
0
);
-- 1: data_o contains the result of last read operation. Core is ready to initiate
-- another transfer.
ready_o
:
out
std_logic
;
-- data read from selected slave, valid when ready_o == 1.
data_o
:
out
std_logic_vector
(
g_num_data_bits
-
1
downto
0
);
-- these are obvious
spi_cs_n_o
:
out
std_logic
;
spi_sclk_o
:
out
std_logic
;
spi_mosi_o
:
out
std_logic
;
spi_miso_i
:
in
std_logic
);
end
gc_simple_spi_master
;
architecture
behavioral
of
gc_simple_spi_master
is
signal
divider
:
unsigned
(
11
downto
0
);
signal
tick
:
std_logic
;
signal
sreg
:
std_logic_vector
(
g_num_data_bits
-1
downto
0
);
signal
rx_sreg
:
std_logic_vector
(
g_num_data_bits
-1
downto
0
);
type
t_state
is
(
IDLE
,
TX_CS
,
TX_DAT1
,
TX_DAT2
,
TX_SCK1
,
TX_SCK2
,
TX_CS2
,
TX_GAP
);
signal
state
:
t_state
;
signal
sclk
:
std_logic
;
signal
counter
:
unsigned
(
4
downto
0
);
begin
-- rtl
-- Simple clock divder. Produces a 'tick' signal which defines the timing for
-- the main state machine transitions.
p_divide_spi_clock
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
divider
<=
(
others
=>
'0'
);
else
if
(
start_i
=
'1'
or
tick
=
'1'
)
then
divider
<=
(
others
=>
'0'
);
else
divider
<=
divider
+
1
;
end
if
;
end
if
;
end
if
;
end
process
;
tick
<=
divider
(
g_div_ratio_log2
);
-- Main state machine. Executes SPI transfers
p_main_fsm
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
state
<=
IDLE
;
sclk
<=
'0'
;
sreg
<=
(
others
=>
'0'
);
rx_sreg
<=
(
others
=>
'0'
);
spi_mosi_o
<=
'0'
;
counter
<=
(
others
=>
'0'
);
else
case
state
is
-- Waits for start of transfer command
when
IDLE
=>
sclk
<=
'0'
;
counter
<=
(
others
=>
'0'
);
if
(
start_i
=
'1'
)
then
sreg
<=
data_i
;
state
<=
TX_CS
;
spi_mosi_o
<=
data_i
(
sreg
'high
);
end
if
;
-- Generates a gap between the externally asserted Chip Select and
-- the beginning of data transfer
when
TX_CS
=>
if
tick
=
'1'
then
state
<=
TX_DAT1
;
end
if
;
-- Outputs subsequent bits to MOSI line.
when
TX_DAT1
=>
if
(
tick
=
'1'
)
then
spi_mosi_o
<=
sreg
(
sreg
'high
);
sreg
<=
sreg
(
sreg
'high
-1
downto
0
)
&
'0'
;
state
<=
TX_SCK1
;
end
if
;
-- Flips the SCLK (active edge)
when
TX_SCK1
=>
if
(
tick
=
'1'
)
then
sclk
<=
not
sclk
;
counter
<=
counter
+
1
;
state
<=
TX_DAT2
;
end
if
;
-- Shifts in bits read from the slave
when
TX_DAT2
=>
if
(
tick
=
'1'
)
then
rx_sreg
<=
rx_sreg
(
rx_sreg
'high
-1
downto
0
)
&
spi_miso_i
;
state
<=
TX_SCK2
;
end
if
;
-- Flips the SCLK (inactive edge). Checks if all bits have been
-- transferred.
when
TX_SCK2
=>
if
(
tick
=
'1'
)
then
sclk
<=
not
sclk
;
if
(
counter
=
g_num_data_bits
)
then
state
<=
TX_CS2
;
else
state
<=
TX_DAT1
;
end
if
;
end
if
;
-- Generates a gap for de-assertoin of CS line
when
TX_CS2
=>
if
(
tick
=
'1'
)
then
state
<=
TX_GAP
;
data_o
<=
rx_sreg
;
end
if
;
when
TX_GAP
=>
if
(
tick
=
'1'
)
then
state
<=
IDLE
;
end
if
;
end
case
;
end
if
;
end
if
;
end
process
;
ready_o
<=
'1'
when
(
state
=
IDLE
and
start_i
=
'0'
)
else
'0'
;
-- SCLK polarity control
spi_sclk_o
<=
sclk
xor
cpol_i
;
spi_cs_n_o
<=
not
cs_i
;
end
behavioral
;
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment