Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cMIPS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Harbor Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD 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
Show more breadcrumbs
Roberto Hexsel
cMIPS
Commits
2c424a99
There was a problem fetching the pipeline summary.
Commit
2c424a99
authored
9 years ago
by
Roberto Hexsel
Browse files
Options
Downloads
Patches
Plain Diff
SDRAM controller's state machine written
parent
eea4da3a
No related branches found
No related tags found
No related merge requests found
Pipeline
#
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
cMIPS/bin/build.sh
+1
-1
1 addition, 1 deletion
cMIPS/bin/build.sh
cMIPS/vhdl/sdram.vhd
+337
-27
337 additions, 27 deletions
cMIPS/vhdl/sdram.vhd
cMIPS/vhdl/tb_cMIPS.vhd
+48
-0
48 additions, 0 deletions
cMIPS/vhdl/tb_cMIPS.vhd
with
386 additions
and
28 deletions
cMIPS/bin/build.sh
+
1
−
1
View file @
2c424a99
...
...
@@ -66,7 +66,7 @@ simulator=tb_cmips
pkg
=
"packageWires.vhd packageMemory.vhd packageExcp.vhd"
src
=
"aux.vhd altera.vhd macnica.vhd memory.vhd cache.vhd instrcache.vhd ram.vhd rom.vhd units.vhd io.vhd uart.vhd fpu.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
src
=
"aux.vhd altera.vhd macnica.vhd memory.vhd cache.vhd instrcache.vhd
sdram.vhd
ram.vhd rom.vhd units.vhd io.vhd uart.vhd fpu.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
# build simulator
#ghdl --clean
...
...
This diff is collapsed.
Click to expand it.
cMIPS/vhdl/sdram.vhd
+
337
−
27
View file @
2c424a99
...
...
@@ -33,12 +33,12 @@ use work.p_wires.all;
use
work
.
p_memory
.
all
;
entity
SDRAM_controller
is
port
(
rst
:
in
std_logic
;
-- FPGA reset
clk
:
in
std_logic
;
-- 100MHz clock
port
(
rst
:
in
std_logic
;
-- FPGA reset
(=0)
clk
2x
:
in
std_logic
;
-- 100MHz clock
hcs
:
in
std_logic
;
-- host side chip select
rdy
:
in
std_logic
;
-- tell CPU to wait
wr
:
in
std_logic
;
-- host side write enable
hcs
:
in
std_logic
;
-- host side chip select
(=0)
rdy
:
in
std_logic
;
-- tell CPU to wait
(=0)
wr
:
in
std_logic
;
-- host side write enable
(=0)
bsel
:
in
reg4
;
-- byte select
haddr
:
in
reg26
;
-- host side address
hDinp
:
in
reg32
;
-- host side data input
...
...
@@ -56,14 +56,58 @@ entity SDRAM_controller is
saddr
:
out
reg12
;
-- ram side address
sdata
:
inout
reg16
);
-- ram side data
type
sdram_cmd
is
(
cmd_NOP
,
cmd_PALL
,
cmd_ARF
,
cmd_LMR
,
cmd_ACT
,
cmd_RD
,
cmd_WR
,
cmd_invalid
);
constant
REFRESH_doit
:
integer
:
=
704
;
-- force a refresh every 704 cycles
subtype
cmd_index
is
integer
range
0
to
13
;
constant
cDSL
:
cmd_index
:
=
0
;
constant
cNOP
:
cmd_index
:
=
1
;
constant
cBST
:
cmd_index
:
=
2
;
constant
cRD
:
cmd_index
:
=
3
;
constant
cRDA
:
cmd_index
:
=
4
;
constant
cWR
:
cmd_index
:
=
5
;
constant
cWRA
:
cmd_index
:
=
6
;
constant
cACT
:
cmd_index
:
=
7
;
constant
cPRE
:
cmd_index
:
=
8
;
constant
cPALL
:
cmd_index
:
=
9
;
constant
cREF
:
cmd_index
:
=
10
;
constant
cSELF
:
cmd_index
:
=
11
;
constant
cMRS
:
cmd_index
:
=
12
;
constant
cinv
:
cmd_index
:
=
13
;
type
t_cmd_type
is
record
cmd
:
cmd_index
;
cs
:
std_logic
;
ras
:
std_logic
;
cas
:
std_logic
;
we
:
std_logic
;
a10
:
std_logic
;
end
record
;
type
t_cmd_mem
is
array
(
0
to
12
)
of
t_cmd_type
;
end
entity
SDRAM_controller
;
end
entity
SDRAM_controller
;
architecture
simple
of
SDRAM_controller
is
constant
cmd_table
:
t_cmd_mem
:
=
(
-- page 9
-- cmd cs ras cas we a10
(
cDSL
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
),
-- DESL device deselect
(
cNOP
,
'0'
,
'1'
,
'1'
,
'1'
,
'1'
),
-- NOP no operation
(
cBST
,
'0'
,
'1'
,
'1'
,
'0'
,
'1'
),
-- BST burst stop
(
cRD
,
'0'
,
'1'
,
'0'
,
'1'
,
'0'
),
-- RD read
(
cRDA
,
'0'
,
'1'
,
'0'
,
'1'
,
'1'
),
-- RDA read with auto precharge
(
cWR
,
'0'
,
'1'
,
'0'
,
'0'
,
'0'
),
-- WR write
(
cWRA
,
'0'
,
'1'
,
'0'
,
'0'
,
'1'
),
-- WR write with auto precharge
(
cACT
,
'0'
,
'0'
,
'1'
,
'1'
,
'1'
),
-- ACT bank activate
(
cPRE
,
'0'
,
'0'
,
'1'
,
'0'
,
'0'
),
-- PRE precharge selected bank
(
cPALL
,
'0'
,
'0'
,
'1'
,
'0'
,
'1'
),
-- PALL precharge all banks
(
cREF
,
'0'
,
'0'
,
'0'
,
'1'
,
'1'
),
-- REF CBR auto-refresh
(
cSELF
,
'0'
,
'0'
,
'0'
,
'1'
,
'1'
),
-- SELF self-refresh
(
cMRS
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
)
-- MRS mode register set
);
component
registerN
is
generic
(
NUM_BITS
:
integer
;
INIT_VAL
:
std_logic_vector
);
port
(
clk
,
rst
,
ld
:
in
std_logic
;
...
...
@@ -71,52 +115,318 @@ architecture simple of SDRAM_controller is
Q
:
out
std_logic_vector
);
end
component
registerN
;
signal
reset_done
,
same_row
:
boolean
:
=
FALSE
;
-- state machine
type
ctrl_state
is
(
st_noreset
,
-- 0
st_in0
,
st_in1
,
st_ipre
,
st_in2
,
-- 4
st_aref1
,
st_1n0
,
st_1n1
,
st_1n2
,
st_1n3
,
st_1n4
,
st_1n5
,
-- 11
st_aref2
,
st_2n0
,
st_2n1
,
st_2n2
,
st_2n3
,
st_2n4
,
st_2n5
,
-- 18
st_aref3
,
st_3n0
,
st_3n1
,
st_3n2
,
st_3n3
,
st_3n4
,
st_3n5
,
-- 25
st_aref4
,
st_4n0
,
st_4n1
,
st_4n2
,
st_4n3
,
st_4n4
,
st_4n5
,
-- 32
st_lmr
,
st_ln0
,
st_ln1
,
-- 35
st_pall
,
st_pn0
,
st_pn1
,
-- 38
st_refr
,
st_rn0
,
st_rn1
,
st_rn2
,
st_rn3
,
st_rn4
,
st_rn5
,
-- 45
st_idle2
,
-- 46
st_act
,
st_an0
,
st_an1
,
-- 49
st_rdcol
,
st_rdn0
,
st_rd_done
,
-- 52
st_wrcol
,
-- 53
st_idle
);
-- 54
signal
curr_st
,
next_st
:
ctrl_state
;
signal
ctrl_dbg_st
:
integer
;
-- for debugging only
signal
reset_done
,
same_row
,
do_refresh
,
refresh_done
:
boolean
:
=
FALSE
;
signal
is_accs
,
is_rd
,
is_wr
:
boolean
:
=
FALSE
;
signal
addr
:
reg26
;
signal
last_row
:
reg13
;
signal
row_bits
,
last_row
:
reg13
;
signal
col_bits
:
reg10
;
signal
rwo_bits
:
reg13
;
signal
ld_old
:
std_logic
;
signal
command
:
t_cmd_type
;
signal
doit
:
cmd_index
;
begin
-- simple
command
<=
cmd_table
(
doit
);
scs
<=
command
.
cs
;
ras
<=
command
.
ras
;
cas
<=
command
.
cas
;
we
<=
command
.
we
;
saddr
(
10
)
<=
addr
(
10
)
when
command
.
cmd
=
cACT
else
command
.
a10
;
U_address
:
registerN
generic
map
(
26
,
b"00"
&
x"000000"
)
port
map
(
clk
,
rst
,
hcs
,
haddr
,
addr
);
port
map
(
clk
2x
,
rst
,
hcs
,
haddr
,
addr
);
row_bits
<=
addr
(
23
downto
11
);
col_bits
<=
addr
(
10
downto
1
);
ba0
<=
addr
(
24
);
ba1
<=
addr
(
25
);
U_last_row
:
registerN
generic
map
(
13
,
'0'
&
x"000"
)
port
map
(
clk
,
rst
,
active
,
haddr
(
23
downto
11
),
last_row
);
ld_old
<=
hcs
and
not
(
BOOL2SL
(
same_row
));
U_last_row
:
registerN
generic
map
(
13
,
'1'
&
x"fff"
)
port
map
(
clk2x
,
rst
,
ld_old
,
haddr
(
23
downto
11
),
last_row
);
same_row
<=
(
last_row
=
row_bits
)
and
(
command
.
cmd
/=
cPALL
);
-- this state machine contols the SDRAM interface -----------------------
U_CTRL_st_reg
:
process
(
rst
,
clk2x
)
begin
if
rst
=
'0'
then
curr_st
<=
st_noreset
;
elsif
rising_edge
(
clk2x
)
then
curr_st
<=
next_st
;
end
if
;
end
process
U_CTRL_st_reg
;
----------------------------------------------
ctrl_dbg_st
<=
integer
(
ctrl_state
'pos
(
curr_st
));
-- for debugging
U_CTRL_st_transitions
:
process
(
curr_st
,
reset_done
,
do_refresh
,
-------
same_row
,
is_accs
,
is_rd
,
is_wr
)
begin
case
curr_st
is
-- WAIT FOR POWER-ON RESET TO COMPLETE
when
st_noreset
=>
-- 0
if
reset_done
then
next_st
<=
st_in0
;
else
next_st
<=
st_noreset
;
end
if
;
-- purpose: wait for 100us after reset
U_rst_100us
:
process
(
clk2x
,
rst
)
variable
cnt
:
integer
:
=
0
;
begin
-- process clk2x
-- INITIALIZATION SEQUENCE
when
st_in0
=>
-- 1 nop
next_st
<=
st_in1
;
when
st_in1
=>
-- 2 nop
next_st
<=
st_ipre
;
when
st_ipre
=>
-- 3 precharge all banks
next_st
<=
st_in2
;
when
st_in2
=>
-- 4 nop
next_st
<=
st_aref1
;
when
st_aref1
=>
-- 5 auto refresh 1 + 60ns delay
next_st
<=
st_1n0
;
when
st_1n0
=>
-- 6 nop
next_st
<=
st_1n1
;
when
st_1n1
=>
-- 7 nop
next_st
<=
st_1n2
;
when
st_1n2
=>
-- 8 nop
next_st
<=
st_1n3
;
when
st_1n3
=>
-- 9 nop
next_st
<=
st_1n4
;
when
st_1n4
=>
-- 10 nop
next_st
<=
st_1n5
;
when
st_1n5
=>
-- 11 nop
next_st
<=
st_aref2
;
when
st_aref2
=>
-- 12 auto refresh 2 + 60ns delay
next_st
<=
st_2n0
;
when
st_2n0
=>
-- 13 nop
next_st
<=
st_2n1
;
when
st_2n1
=>
-- 14 nop
next_st
<=
st_2n2
;
when
st_2n2
=>
-- 15 nop
next_st
<=
st_2n3
;
when
st_2n3
=>
-- 16 nop
next_st
<=
st_2n4
;
when
st_2n4
=>
-- 17 nop
next_st
<=
st_2n5
;
when
st_2n5
=>
-- 18 nop
next_st
<=
st_aref3
;
when
st_aref3
=>
-- 19 auto refresh 3 + 60ns delay
next_st
<=
st_3n0
;
when
st_3n0
=>
-- 20 nop
next_st
<=
st_3n1
;
when
st_3n1
=>
-- 21 nop
next_st
<=
st_3n2
;
when
st_3n2
=>
-- 22 nop
next_st
<=
st_3n3
;
when
st_3n3
=>
-- 23 nop
next_st
<=
st_3n4
;
when
st_3n4
=>
-- 24 nop
next_st
<=
st_3n5
;
when
st_3n5
=>
-- 25 nop
next_st
<=
st_aref4
;
when
st_aref4
=>
-- 26 auto refresh 4 + 60ns delay
next_st
<=
st_4n0
;
when
st_4n0
=>
-- 27 nop
next_st
<=
st_4n1
;
when
st_4n1
=>
-- 28 nop
next_st
<=
st_4n2
;
when
st_4n2
=>
-- 29 nop
next_st
<=
st_4n3
;
when
st_4n3
=>
-- 30 nop
next_st
<=
st_4n4
;
when
st_4n4
=>
-- 31 nop
next_st
<=
st_4n5
;
when
st_4n5
=>
-- 32 nop
next_st
<=
st_lmr
;
when
st_lmr
=>
-- 33 load mode register + 2 nops
next_st
<=
st_ln0
;
when
st_ln0
=>
-- 34 nop
next_st
<=
st_ln1
;
when
st_ln1
=>
-- 35 nop
next_st
<=
st_idle
;
-- AUTO-REFRESH SEQUENCE
when
st_pall
=>
-- 36 precharge all banks + 2 nops
next_st
<=
st_pn0
;
when
st_pn0
=>
-- 37 nop
next_st
<=
st_pn1
;
when
st_pn1
=>
-- 38 nop
next_st
<=
st_refr
;
when
st_refr
=>
-- 39 auto refresh + 60ns delay
next_st
<=
st_rn0
;
when
st_rn0
=>
-- 40 nop
next_st
<=
st_rn1
;
when
st_rn1
=>
-- 41 nop
next_st
<=
st_rn2
;
when
st_rn2
=>
-- 42 nop
next_st
<=
st_rn3
;
when
st_rn3
=>
-- 43 nop
next_st
<=
st_rn4
;
when
st_rn4
=>
-- 44 nop
next_st
<=
st_rn5
;
when
st_rn5
=>
-- 45 nop; sameRow was cleared
next_st
<=
st_idle2
;
when
st_idle2
=>
-- 46
if
is_accs
then
-- is post-refresh access, activate row
next_st
<=
st_act
;
else
next_st
<=
st_idle2
;
end
if
;
-- ACTIVATE NEW ROW
when
st_act
=>
-- 47 activate row + 2 nops
next_st
<=
st_an0
;
when
st_an0
=>
-- 48 nop
next_st
<=
st_an1
;
when
st_an1
=>
-- 49 nop
if
is_rd
then
next_st
<=
st_rdcol
;
-- access is a read, set column
else
next_st
<=
st_wrcol
;
-- access is a write, set column
end
if
;
-- READ FROM COLUMN
when
st_rdcol
=>
-- 50 set column for RD + 2 nops
next_st
<=
st_rdn0
;
when
st_rdn0
=>
-- 51 nop
next_st
<=
st_rd_done
;
when
st_rd_done
=>
-- 52 nop
if
do_refresh
then
next_st
<=
st_pall
;
-- go to refresh sequence
else
next_st
<=
st_idle
;
-- wait for next access to same row
end
if
;
-- WRITE TO COLUMN
when
st_wrcol
=>
-- 53 set column for WR
if
do_refresh
then
next_st
<=
st_pall
;
-- go to refresh sequence
else
next_st
<=
st_idle
;
-- wait for next access to same row
end
if
;
when
st_idle
=>
-- 54
if
is_accs
and
not
(
same_row
)
then
next_st
<=
st_act
;
elsif
is_rd
then
next_st
<=
st_rdcol
;
elsif
is_wr
then
next_st
<=
st_rdcol
;
else
next_st
<=
st_idle
;
end
if
;
when
others
=>
assert
false
report
"CTRL stateMachine broken"
&
integer
'image
(
ctrl_state
'pos
(
curr_st
))
severity
failure
;
end
case
;
end
process
U_CTRL_st_transitions
;
------------------------------------
U_CTRL_outputs
:
process
(
curr_st
)
------------------------------
begin
case
curr_st
is
when
st_rdcol
=>
doit
<=
cRD
;
-- read from column
when
st_wrcol
=>
doit
<=
cWR
;
-- write to column
when
st_ipre
|
st_pall
=>
doit
<=
cPALL
;
-- precharge all banks
when
st_aref1
|
st_aref2
|
st_aref3
|
st_aref4
=>
doit
<=
cREF
;
-- auto-refresh
when
st_lmr
=>
doit
<=
cMRS
;
-- load mode register
when
st_act
=>
doit
<=
cACT
;
-- activate row
when
others
=>
doit
<=
cNOP
;
end
case
;
end
process
U_CTRL_outputs
;
-------------------------------------------
-- do a refresh in less than 7,8us (8192 in 64ms @ 100MHz)
U_do_refresh
:
process
(
rst
,
clk2x
,
refresh_done
)
variable
cnt
:
integer
range
0
to
1023
:
=
0
;
begin
if
rst
=
'0'
then
do_refresh
<=
FALSE
;
cnt
:
=
0
;
elsif
rising_edge
(
clk2x
)
then
if
cnt
>
REFRESH_doit
then
if
refresh_done
then
do_refresh
<=
FALSE
;
cnt
:
=
0
;
else
do_refresh
<=
TRUE
;
-- add some hysteresis
cnt
:
=
cnt
+
1
;
-- to accomodate slow commands
end
if
;
else
do_refresh
<=
FALSE
;
cnt
:
=
cnt
+
1
;
end
if
;
end
if
;
end
process
U_do_refresh
;
-- do wait for 100us after reset
U_rst_100us
:
process
variable
cnt
:
integer
range
0
to
16383
:
=
0
;
begin
-- process clk2x
reset_done
<=
FALSE
;
elsif
rising_edge
(
clk
)
then
wait
until
rst
=
'1'
;
cnt
:
=
0
;
wait
until
rising_edge
(
clk2x
);
cnt
:
=
cnt
+
1
;
if
cnt
=
10000
then
-- 100us elapsed
reset_done
<=
TRUE
;
wait
;
end
if
;
end
if
;
end
process
clk2x
;
end
process
U_rst_100us
;
end
simple
;
-- ---------------------------------------------------------------------
This diff is collapsed.
Click to expand it.
cMIPS/vhdl/tb_cMIPS.vhd
+
48
−
0
View file @
2c424a99
...
...
@@ -287,6 +287,29 @@ architecture TB of tb_cMIPS is
dump_ram
:
in
std_logic
);
end
component
fpga_RAM
;
component
SDRAM_controller
is
port
(
rst
:
in
std_logic
;
-- FPGA reset (=0)
clk2x
:
in
std_logic
;
-- 100MHz clock
hcs
:
in
std_logic
;
-- host side chip select (=0)
rdy
:
in
std_logic
;
-- tell CPU to wait (=0)
wr
:
in
std_logic
;
-- host side write enable (=0)
bsel
:
in
reg4
;
-- byte select
haddr
:
in
reg26
;
-- host side address
hDinp
:
in
reg32
;
-- host side data input
hDout
:
out
reg32
;
-- host side data output
cke
:
out
std_logic
;
-- ram side clock enable
scs
:
out
std_logic
;
-- ram side chip select
ras
:
out
std_logic
;
-- ram side RAS
cas
:
out
std_logic
;
-- ram side CAS
we
:
out
std_logic
;
-- ram side write enable
dqm0
:
out
std_logic
;
-- ram side byte0 output enable
dqm1
:
out
std_logic
;
-- ram side byte0 output enable
ba0
:
out
std_logic
;
-- ram side bank select 0
ba1
:
out
std_logic
;
-- ram side bank select 1
saddr
:
out
reg12
;
-- ram side address
sdata
:
inout
reg16
);
-- ram side data
end
component
SDRAM_controller
;
component
fake_I_CACHE
is
port
(
rst
:
in
std_logic
;
clk4x
:
in
std_logic
;
...
...
@@ -478,6 +501,27 @@ architecture TB of tb_cMIPS is
signal
LCD_RS
,
LCD_RW
,
LCD_EN
,
LCD_BLON
:
std_logic
;
-- LCD control
signal
uart_txd
,
uart_rxd
,
uart_rts
,
uart_cts
,
uart_irq
:
std_logic
;
signal
hcs
:
std_logic
;
-- host side chip select (=0)
signal
sdram_rdy
:
std_logic
;
-- host side chip select (=0)
signal
haddr
:
reg26
;
-- host side address
signal
hDinp
:
reg32
;
-- host side data input
signal
hDout
:
reg32
;
-- host side data output
signal
sdcke
:
std_logic
;
-- ram side clock enable
signal
sdscs
:
std_logic
;
-- ram side chip select
signal
sdras
:
std_logic
;
-- ram side RAS
signal
sdcas
:
std_logic
;
-- ram side CAS
signal
sdwe
:
std_logic
;
-- ram side write enable
signal
sddqm0
:
std_logic
;
-- ram side byte0 output enable
signal
sddqm1
:
std_logic
;
-- ram side byte0 output enable
signal
sdba0
:
std_logic
;
-- ram side bank select 0
signal
sdba1
:
std_logic
;
-- ram side bank select 1
signal
sdaddr
:
reg12
;
-- ram side address
signal
sddata
:
reg16
;
-- ram side data
begin
-- TB
...
...
@@ -587,6 +631,10 @@ begin -- TB
mem_addr
,
datram_out
,
datram_inp
,
mem_xfer
,
dump_ram
);
U_SDRAM_controller
:
SDRAM_controller
port
map
(
rst
,
clk
,
hcs
,
sdram_rdy
,
wr
,
cpu_xfer
,
haddr
,
hDinp
,
hDout
,
sdcke
,
sdscs
,
sdras
,
sdcas
,
sdwe
,
sddqm0
,
sddqm1
,
sdba0
,
sdba1
,
sdaddr
,
sddata
);
U_to_stdout
:
to_stdout
port
map
(
rst
,
clk
,
io_stdout_sel
,
wr
,
cpu_data
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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