Initial import

git-svn-id: http://moon:8086/svn/vhdl/trunk@5 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-08-23 08:20:30 +00:00
parent bfbeba5129
commit d3bd08bb52
160 changed files with 56260 additions and 0 deletions
@@ -0,0 +1,13 @@
vhdl work "W:\vhdl\lib\misc\utils_pkg.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_config.vhd"
vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_types.vhd"
vhdl work "W:\vhdl\lib\FIFO\src\sync_fifo_ctrl.vhd"
vhdl work "W:\vhdl\lib\FIFO\src\dpram.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_ctrl.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_cmd.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\reset_virtex4.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\fifo_sync.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\ddr_phy_virtex4.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\clockgen_virtex4.vhd"
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_ctrl_top.vhd"
@@ -0,0 +1,6 @@
vlib simprim
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vcomponents_mti.vhd
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vpackage_mti.vhd
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_SMODEL_mti.vhd
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_VITAL_mti.vhd
@@ -0,0 +1,6 @@
vlib unisim
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vpkg.vhd
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vcomp.vhd
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_smodel.vhd
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vital.vhd
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl
do {tb_sdr_ctrl.wdo}
view wave
view structure
view signals
run 800us
@@ -0,0 +1,93 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Main controller}
add wave -noupdate -divider {Main controller}
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_ctrl/st_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/st_sdr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/burst_finished
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/mode_fifo_in
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/mode_fifo_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/col_fifo_in
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/col_fifo_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_in
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_out
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_empty
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_full
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_re
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/cmd_fifo_we
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Logic /tb_sdr_ctrl/clk
add wave -noupdate -format Logic /tb_sdr_ctrl/rst
add wave -noupdate -format Logic /tb_sdr_ctrl/rst_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_fb
add wave -noupdate -format Analog-Step -height 50 -offset 0.5 -scale 20.0 /tb_sdr_ctrl/efficiency
add wave -noupdate -format Literal /tb_sdr_ctrl/data_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/cycle_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_we_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cke
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_zen
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_rst
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_drive
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive270
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_en
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_clk
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal /tb_sdr_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/u_busy
add wave -noupdate -format Logic /tb_sdr_ctrl/u_data_vld
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/sys_clk0
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/ref_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {14963876 ps} 0}
configure wave -namecolwidth 184
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {14733925 ps} {15711632 ps}
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl_fifo.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl_fifo
do {tb_sdr_ctrl_fifo.wdo}
view wave
view structure
view signals
run 20us
@@ -0,0 +1,68 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/rst_out
add wave -noupdate -format Literal /tb_sdr_ctrl_fifo/inst_sdram_ctrl/inst_sdram_cmd/st_sdr
add wave -noupdate -format Literal /tb_sdr_ctrl_fifo/inst_sdram_ctrl/inst_sdram_cmd/cmd
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_sdram_ctrl/inst_sdram_cmd/cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_we_n
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_sdram_ctrl/sd_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/u_addr
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/u_busy
add wave -noupdate -format Literal /tb_sdr_ctrl_fifo/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/u_cmd_we
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/u_data_r
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/u_data_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/u_data_w
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/u_req_rd
add wave -noupdate -divider {Read FIFO}
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/read_fifo_empty
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/read_fifo_we
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/read_fifo_re
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/read_fifo_dout
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/was_write
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/pr
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/pr_next
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/pw
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/pw_next
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/fifo_full
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_read_fifo/inst_sync_fifo_ctrl/fifo_empty
add wave -noupdate -divider {Write FIFO}
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_write_fifo/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_write_fifo/data_w
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_write_fifo/we
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_write_fifo/re
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_write_fifo/fifo_empty
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_write_fifo/fifo_full
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_write_fifo/inst_sync_fifo_ctrl/pr
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_write_fifo/inst_sync_fifo_ctrl/pr_next
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_write_fifo/inst_sync_fifo_ctrl/pw
add wave -noupdate -format Literal -radix unsigned /tb_sdr_ctrl_fifo/inst_write_fifo/inst_sync_fifo_ctrl/pw_next
add wave -noupdate -divider {Command FIFO}
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_command_fifo/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl_fifo/inst_command_fifo/data_w
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_command_fifo/we
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_command_fifo/re
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_command_fifo/inst_sync_fifo_ctrl/fifo_empty
add wave -noupdate -format Logic /tb_sdr_ctrl_fifo/inst_command_fifo/inst_sync_fifo_ctrl/fifo_full
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {13893123 ps} 0}
configure wave -namecolwidth 172
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {13879998 ps} {13928553 ps}
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl_lin_r_rand_w.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl
do {tb_sdr_ctrl_lin_r_rand_w.wdo}
view wave
view structure
view signals
run 1200us
@@ -0,0 +1,87 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Main controller}
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/burst_finished
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/clk
add wave -noupdate -format Logic /tb_sdr_ctrl/rst
add wave -noupdate -format Logic /tb_sdr_ctrl/rst_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_fb
add wave -noupdate -format Analog-Step -height 50 -offset 0.5 -scale 20.0 /tb_sdr_ctrl/efficiency
add wave -noupdate -format Literal /tb_sdr_ctrl/data_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/cycle_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_we_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cke
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_zen
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_rst
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_drive
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive270
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/rw_null_en
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_en
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_clk
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal /tb_sdr_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/u_busy
add wave -noupdate -format Logic /tb_sdr_ctrl/u_data_vld
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/sys_clk0
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/ref_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {21813900 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {21725359 ps} {22204052 ps}
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl_lin_w_rand_r.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl
do {tb_sdr_ctrl_lin_w_rand_r.wdo}
view wave
view structure
view signals
run 1200us
@@ -0,0 +1,87 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Main controller}
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/burst_finished
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/clk
add wave -noupdate -format Logic /tb_sdr_ctrl/rst
add wave -noupdate -format Logic /tb_sdr_ctrl/rst_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_fb
add wave -noupdate -format Analog-Step -height 50 -offset 0.5 -scale 20.0 /tb_sdr_ctrl/efficiency
add wave -noupdate -format Literal /tb_sdr_ctrl/data_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/cycle_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_we_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cke
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_zen
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_rst
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_drive
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive270
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/rw_null_en
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_en
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_clk
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal /tb_sdr_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/u_busy
add wave -noupdate -format Logic /tb_sdr_ctrl/u_data_vld
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/sys_clk0
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/ref_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {21813900 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {21725359 ps} {22204052 ps}
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl_rand_addr.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl
do {tb_sdr_ctrl_rand_rw.wdo}
view wave
view structure
view signals
run 1000us
@@ -0,0 +1,82 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/burst_finished
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/clk
add wave -noupdate -format Logic /tb_sdr_ctrl/rst
add wave -noupdate -format Logic /tb_sdr_ctrl/rst_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_fb
add wave -noupdate -format Analog-Step -height 50 -offset 0.5 -scale 20.0 /tb_sdr_ctrl/efficiency
add wave -noupdate -format Literal /tb_sdr_ctrl/data_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/cycle_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_we_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cke
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_zen
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_rst
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_drive
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive270
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_en
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_clk
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal /tb_sdr_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/u_busy
add wave -noupdate -format Logic /tb_sdr_ctrl/u_data_vld
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/sys_clk0
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/ref_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {60573747 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {60552548 ps} {60600861 ps}
@@ -0,0 +1,27 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdr_ctrl_rand_rw.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdr_ctrl
do {tb_sdr_ctrl_rand_rw.wdo}
view wave
view structure
view signals
run 10000us
@@ -0,0 +1,84 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_sdram_cmd/burst_finished
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_in
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_wr
add wave -noupdate -format Literal /tb_sdr_ctrl/u_tag_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/clk
add wave -noupdate -format Logic /tb_sdr_ctrl/rst
add wave -noupdate -format Logic /tb_sdr_ctrl/rst_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_fb
add wave -noupdate -format Analog-Step -height 50 -offset 0.5 -scale 20.0 /tb_sdr_ctrl/efficiency
add wave -noupdate -format Literal /tb_sdr_ctrl/data_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/cycle_cnt
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_we_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cs_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_ras_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cas_n
add wave -noupdate -format Logic /tb_sdr_ctrl/part_cke
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_zen
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_rst
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_p
add wave -noupdate -format Logic /tb_sdr_ctrl/part_clk_n
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dqs
add wave -noupdate -format Literal /tb_sdr_ctrl/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_addr
add wave -noupdate -format Literal /tb_sdr_ctrl/part_ba
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/part_data
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/dqs_drive
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/drive270
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -divider {Main controller}
add wave -noupdate -format Logic /tb_sdr_ctrl/rw_null_en
add wave -noupdate -format Literal /tb_sdr_ctrl/test_phase
add wave -noupdate -format Literal /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/sd_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_en
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/read_clk
add wave -noupdate -format Logic /tb_sdr_ctrl/clk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal /tb_sdr_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_cmd_we
add wave -noupdate -format Logic /tb_sdr_ctrl/u_busy
add wave -noupdate -format Logic /tb_sdr_ctrl/u_data_vld
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_rd
add wave -noupdate -format Logic /tb_sdr_ctrl/u_req_wr
add wave -noupdate -format Logic /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/sys_clk0
add wave -noupdate -format Literal -expand /tb_sdr_ctrl/inst_sdram_ctrl/phy_ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/inst_sdram_ctrl/inst_ddr_phy/data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/ref_data
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_r
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_data_w
add wave -noupdate -format Literal -radix hexadecimal /tb_sdr_ctrl/u_addr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {16004147 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {15914249 ps} {16324366 ps}
@@ -0,0 +1,28 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r.vhd"
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/sdram_config.vhd"
vcom -explicit -93 "../src/sdram_types.vhd"
vcom -explicit -93 "../src/reset_virtex4.vhd"
vcom -explicit -93 "../src/clockgen_virtex4.vhd"
vcom -explicit -93 "../src/sdram_cmd.vhd"
vcom -explicit -93 "../src/sdram_ctrl.vhd"
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
vcom -explicit -93 "../src/sdram_ctrl_frontend.vhd"
vcom -explicit -93 "../src/mt46v16m16.vhd"
vcom -explicit -93 "../src/tb_sdram_ctrl_frontend.vhd"
#restart -force
vsim -t 1ps -lib work tb_sdram_ctrl_frontend
do {tb_sdram_ctrl_frontend.wdo}
view wave
view structure
view signals
run 40us
@@ -0,0 +1,45 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/addr
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/busy
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/en
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/r_wn
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/din
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/be
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/dout
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/dout_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/dout_reg
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/clk_out
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/part_cs_n
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/part_we_n
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/part_ras_n
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/part_cas_n
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/part_ba
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/part_dm
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/part_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend/part_data
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_ctrl/u_busy
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_ctrl/u_cmd
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_ctrl/u_cmd_we
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_ctrl/st_ctrl
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_cmd/st_sdr
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/inst_sdram_ctrl/inst_sdram_ctrl/sdr_cmd_busy
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/cat_fifo_full
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/write_fifo_full
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend/inst_sdram_ctrl_frontend/read_fifo_full
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {27951315 ps} 0}
configure wave -namecolwidth 172
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {42 us}
@@ -0,0 +1,240 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: Clock generator (Virtex-4 specific)
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library ieee, work;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
Library UNISIM;
use UNISIM.vcomponents.all;
entity clockgen is
generic
(
read_phaseshift : integer := 0;
frequency_hz : integer := 100E6
);
port
(
-- Clocks and Reset
rst : in std_logic; -- external async reset, low active
clk_in : in std_logic; -- system clock (e.g. 100MHz), from board
clk_fb_in : in std_logic; -- feedback clock
read_clk0_out : out std_logic; -- Clock for DDR-SDRAM data capture, dcm#1 output 0°
read_clk270_out : out std_logic; -- Clock for DDR-SDRAM data capture, dcm#1 output 270°
sys_clk0_out : out std_logic; -- System clock, dcm#0 output 0°
sys_clk270_out : out std_logic; -- System clock, dcm#0 output 270°
locked_out : out std_logic; -- DCM locked status
error_out : out std_logic -- indicates DCM Errors
);
end;
architecture tech of clockgen is
constant CLKIN_PER : real := real(1000E6/frequency_hz);
signal locked : unsigned(1 downto 0);
signal dcm_rst : unsigned(1 downto 0);
signal read_clk0 : std_logic;
signal read_clk270 : std_logic;
signal read_clk0_bufg : std_logic;
signal read_clk270_bufg : std_logic;
signal sys_clk0 : std_logic;
signal sys_clk270 : std_logic;
signal sys_clk0_bufg : std_logic;
signal sys_clk270_bufg : std_logic;
signal dcm1_locked, dcm2_locked : unsigned(2 downto 0);
signal cnt_q : unsigned(4 downto 0);
type STATE_TYPE is (s0, s1, s2, s3, s4);
signal state_q : STATE_TYPE;
begin
read_clk0_out <= read_clk0_bufg;
read_clk270_out <= read_clk270_bufg;
sys_clk0_out <= sys_clk0_bufg;
sys_clk270_out <= sys_clk270_bufg;
bufg11: bufg
port map
(
o => sys_clk0_bufg,
i => sys_clk0
);
bufg12: bufg
port map (
o => sys_clk270_bufg,
i => sys_clk270
);
bufg13: bufg
port map
(
o => read_clk0_bufg,
i => read_clk0
);
bufg14: bufg
port map (
o => read_clk270_bufg,
i => read_clk270
);
-------------------------------------------------------------------------------------------------------
-- Clock generation
-------------------------------------------------------------------------------------------------------
inst_DCM_BASE_0 : DCM_BASE
generic map (
CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
-- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32
CLKFX_MULTIPLY => 4, -- Can be any integer from 2 to 32
CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature
CLKIN_PERIOD => CLKIN_PER, -- Specify period of input clock in ns from 1.25 to 1000.00
CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift mode of NONE or FIXED
CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE or 1X
DCM_AUTOCALIBRATION => TRUE, -- DCM calibrartion circuitry TRUE/FALSE
DCM_PERFORMANCE_MODE => "MAX_SPEED", -- Can be MAX_SPEED or MAX_RANGE
DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
-- an integer from 0 to 15
DFS_FREQUENCY_MODE => "LOW", -- LOW or HIGH frequency mode for frequency synthesis
DLL_FREQUENCY_MODE => "LOW", -- LOW, HIGH, or HIGH_SER frequency mode for DLL
DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE
FACTORY_JF => X"F0F0", -- FACTORY JF Values Suggested to be set to X"F0F0"
PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 1023
STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE
port map (
CLK0 => sys_clk0, -- 0 degree DCM CLK ouptput
CLK180 => open, -- 180 degree DCM CLK output
CLK270 => sys_clk270, -- 270 degree DCM CLK output
CLK2X => open, -- 2X DCM CLK output
CLK2X180 => open, -- 2X, 180 degree DCM CLK out
CLK90 => open, -- 90 degree DCM CLK output
CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE)
CLKFX => open, -- DCM CLK synthesis out (M/D)
CLKFX180 => open, -- 180 degree CLK synthesis out
LOCKED => locked(0), -- DCM LOCK status output
CLKFB => clk_fb_in, -- DCM clock feedback
CLKIN => clk_in, -- Clock input (from IBUFG, BUFG or DCM)
RST => dcm_rst(0) -- DCM asynchronous reset input
);
inst_DCM_BASE_1 : DCM_BASE
generic map (
CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
-- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32
CLKFX_MULTIPLY => 4, -- Can be any integer from 2 to 32
CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature
CLKIN_PERIOD => CLKIN_PER, -- Specify period of input clock in ns from 1.25 to 1000.00
CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift mode of NONE or FIXED
CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE or 1X
DCM_AUTOCALIBRATION => TRUE, -- DCM calibrartion circuitry TRUE/FALSE
DCM_PERFORMANCE_MODE => "MAX_SPEED", -- Can be MAX_SPEED or MAX_RANGE
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
-- an integer from 0 to 15
DFS_FREQUENCY_MODE => "LOW", -- LOW or HIGH frequency mode for frequency synthesis
DLL_FREQUENCY_MODE => "LOW", -- LOW, HIGH, or HIGH_SER frequency mode for DLL
DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE
FACTORY_JF => X"F0F0", -- FACTORY JF Values Suggested to be set to X"F0F0"
PHASE_SHIFT => read_phaseshift, -- Amount of fixed phase shift from -255 to 1023
STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE
port map (
CLK0 => read_clk0, -- 0 degree DCM CLK ouptput
CLK180 => open, -- 180 degree DCM CLK output
CLK270 => read_clk270, -- 270 degree DCM CLK output
CLK2X => open, -- 2X DCM CLK output
CLK2X180 => open, -- 2X, 180 degree DCM CLK out
CLK90 => open, -- 90 degree DCM CLK output
CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE)
CLKFX => open, -- DCM CLK synthesis out (M/D)
CLKFX180 => open, -- 180 degree CLK synthesis out
LOCKED => locked(1), -- DCM LOCK status output
CLKFB => read_clk0_bufg, -- DCM clock feedback
CLKIN => clk_fb_in, -- Clock input (from IBUFG, BUFG or DCM)
RST => dcm_rst(1) -- DCM asynchronous reset input
);
dcm_rst(1) <= not locked(0);
dcm_fsm:
process(rst, clk_in)
begin
if rst = '1' then
state_q <= s0;
dcm_rst(0) <= '0';
cnt_q <= "11111";
error_out <= '0';
locked_out <= '0';
dcm1_locked <= (others => '0');
dcm2_locked <= (others => '0');
elsif rising_edge(clk_in) then
case state_q is
when s0 =>
state_q <= s1;
when s1 =>
cnt_q <= cnt_q - 1;
if cnt_q = 0 then
dcm_rst(0) <= '1';
state_q <= s2;
end if;
when s2 =>
cnt_q <= cnt_q - 1;
if cnt_q = 0 then
dcm_rst(0) <= '0';
state_q <= s3;
end if;
when s3 =>
if dcm1_locked(2)='1' and dcm2_locked(2)='1' then
state_q <= s4;
error_out <= '0';
end if;
when s4 =>
if dcm1_locked(2)='1' and dcm2_locked(2)='1' then
locked_out <= '1';
else
error_out <= '1';
end if;
end case;
-- synchronize 'dcm1_locked'
dcm1_locked <= dcm1_locked(1 downto 0) & locked(0);
dcm2_locked <= dcm2_locked(1 downto 0) & locked(1);
end if;
end process;
end architecture tech;
@@ -0,0 +1,370 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: DDR physical layer (Virtex-4 specific)
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
Library UNISIM;
use UNISIM.vcomponents.all;
entity ddr_phy is
Port (
sys_rst : in STD_LOGIC;
sys_clk0 : in STD_LOGIC;
sys_clk270 : in STD_LOGIC;
u_tag_in : in user_tag_t;
u_tag_rd : out user_tag_t;
u_tag_wr : out user_tag_t;
read_clk : in STD_LOGIC;
phy_ctrl : in phy_ctrl_t;
part_ctrl : in part_ctrl_t;
sdr_data_w : in unsigned(SDR_DATA_WIDTH-1 downto 0);
sdr_dm : in unsigned(SDR_DM_WIDTH-1 downto 0);
sdr_data_r : out unsigned(SDR_DATA_WIDTH-1 downto 0);
sdr_data_vld : out STD_LOGIC;
sdr_data_req_w : out STD_LOGIC;
sdr_data_req_r : out STD_LOGIC;
part_clk_p : out STD_LOGIC;
part_clk_n : out STD_LOGIC;
part_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
part_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
part_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0);
part_ba : out unsigned(DDR_BANK_WIDTH-1 downto 0);
part_addr : out unsigned(DDR_ADDR_WIDTH-1 downto 0);
part_cs_n : out STD_LOGIC;
part_we_n : out STD_LOGIC;
part_cas_n : out STD_LOGIC;
part_ras_n : out STD_LOGIC;
part_cke : out STD_LOGIC
);
end ddr_phy;
architecture tech of ddr_phy is
signal dqs_drive : std_logic;
signal drive : std_logic;
signal dqs : unsigned(DDR_DQS_WIDTH-1 downto 0);
signal dqs_zen : unsigned(DDR_DQS_WIDTH-1 downto 0);
signal dqs_rst : std_logic;
signal ddr_data_w : unsigned(DDR_DATA_WIDTH-1 downto 0);
signal data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal data_reg_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal drive270 : unsigned(DDR_DATA_WIDTH-1 downto 0);
signal part_ctrl_reg : part_ctrl_t;
signal we_reg : std_logic;
signal read_en : std_logic;
type u_tag_array_t is array (natural range 0 to 4) of user_tag_t;
signal u_tag_pipe : u_tag_array_t;
begin
------------------------------------------------------------------------------------------------------------------------------------------------
utag_pipe:
process(sys_rst, sys_clk0)
begin
if rising_edge(sys_clk0) then
for i in u_tag_pipe'length-1 downto 1 loop
u_tag_pipe(i) <= u_tag_pipe(i-1);
end loop;
if phy_ctrl.utag_we = '1' then
u_tag_pipe(0) <= u_tag_in;
end if;
end if;
end process;
WE_REGISTER:
process(sys_rst, sys_clk0)
begin
if sys_rst = '1' then
we_reg <= '0';
elsif rising_edge(sys_clk0) then
we_reg <= phy_ctrl.we;
end if;
end process;
DATA_DRIVE_GEN:
process(sys_clk0)
begin
if falling_edge(sys_clk0) then
dqs_rst <= not we_reg;
drive <= we_reg;
end if;
end process;
DQS_DRIVE_GEN:
process(sys_clk0)
variable p : unsigned(1 downto 0);
begin
if rising_edge(sys_clk0) then
if phy_ctrl.drive_en = '1' then
p := (others => '1');
else
p := p(p'left-1 downto 0) & '0';
end if;
end if;
dqs_drive <= p(p'left);
end process;
------------------------------------------------------------------------------------------------------------------------------------------------
-- SDRAM Clock
ODDR_clk_p : ODDR
generic map
(
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
)
port map (
Q => part_clk_p, -- 1-bit DDR output
C => sys_clk0, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => '1', -- 1-bit data input (positive edge)
D2 => '0', -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
ODDR_clk_n : ODDR
generic map
(
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
)
port map (
Q => part_clk_n, -- 1-bit DDR output
C => sys_clk0, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => '0', -- 1-bit data input (positive edge)
D2 => '1', -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
------------------------------------------------------------------------------------------------------------------------------------------------
-- Data OUT DDR-FFs
gen_ddr_data_out:
for n in 0 to DDR_DATA_WIDTH-1 generate
begin
ODDR_data : ODDR
generic map
(
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
)
port map (
Q => ddr_data_w(n), -- 1-bit DDR output
C => sys_clk270, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => sdr_data_w(n + DDR_DATA_WIDTH), -- 1-bit data input (positive edge)
D2 => sdr_data_w(n), -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
end generate gen_ddr_data_out;
-- Sample tristate on clock90
process (sys_clk270)
begin
if rising_edge(sys_clk270) then
for n in 0 to DDR_DATA_WIDTH-1 loop
drive270(n) <= drive;
end loop;
end if;
end process;
-- Output mux
out_mux_data:
for n in 0 to DDR_DATA_WIDTH-1 generate
part_data(n) <= ddr_data_w(n) when drive270(n) = '1' else 'Z';
end generate;
------------------------------------------------------------------------------------------------------------------------------------------------
-- Data-mask OUT DDR-FFs
gen_ddr_dm_out:
for n in 0 to DDR_DM_WIDTH-1 generate
begin
ODDR_dm : ODDR
generic map
(
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
)
port map (
Q => part_dm(n), -- 1-bit DDR output
C => sys_clk270, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => sdr_dm(n + DDR_DM_WIDTH), -- 1-bit data input (positive edge)
D2 => sdr_dm(n), -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
end generate gen_ddr_dm_out;
------------------------------------------------------------------------------------------------------------------------------------------------
-- DQS OUT DDR-FFs
gen_dqs_out:
for n in 0 to DDR_DQS_WIDTH-1 generate
begin
ODDR_dqs : ODDR
generic map
(
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
)
port map (
Q => dqs(n), -- 1-bit DDR output
C => sys_clk0, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D2 => '0', -- 1-bit data input (positive edge)
D1 => '1', -- 1-bit data input (negative edge)
R => dqs_rst, -- 1-bit reset input
S => '0' -- 1-bit set input
);
end generate gen_dqs_out;
-- Tristate-Control fuer dqs
process (sys_clk0) is
variable zctrl : boolean;
begin
if rising_edge(sys_clk0) then
if dqs_drive = '1' then
zctrl := false;
else
zctrl := true;
end if;
if zctrl then
dqs_zen <= (others => '1');
else
dqs_zen <= (others => '0');
end if;
end if;
end process;
-- Tristate-Buffer fuer dqs
gen_out_mux_dqs:
for n in 0 to DDR_DQS_WIDTH-1 generate
part_dqs(n) <= 'Z' when dqs_zen(n)='1' else dqs(n);
end generate gen_out_mux_dqs;
------------------------------------------------------------------------------------------------------------------------------------------------
process (sys_rst, sys_clk0) is
begin
if sys_rst = '1' then
part_ctrl_reg.cmd <= COMMAND(SD_DESELECT);
part_ctrl_reg.ba <= (others=>'0');
part_ctrl_reg.addr <= (others=>'0');
part_ctrl_reg.cke <= '0';
elsif rising_edge(sys_clk0) then
part_ctrl_reg <= part_ctrl;
end if;
end process;
process (sys_clk0) is
begin
if falling_edge(sys_clk0) then
part_ras_n <= part_ctrl_reg.cmd.ras_n;
part_cas_n <= part_ctrl_reg.cmd.cas_n;
part_we_n <= part_ctrl_reg.cmd.we_n;
part_cs_n <= part_ctrl_reg.cmd.cs_n;
part_ba <= part_ctrl_reg.ba;
part_addr <= part_ctrl_reg.addr;
part_cke <= part_ctrl_reg.cke;
end if;
end process;
-----------------------------------------------------------------
-- READ DATA Processing
-----------------------------------------------------------------
gen_ddr_data_in:
for n in 0 to DDR_DATA_WIDTH-1 generate
begin
IDDR_data : IDDR
generic map
(
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"
INIT_Q1 => '0', -- Initial value of Q1: '0' or '1'
INIT_Q2 => '0', -- Initial value of Q2: '0' or '1'
SRTYPE => "SYNC" -- Set/Reset type: "SYNC" or "ASYNC"
)
port map
(
Q1 => data_r(n), -- 1-bit output for positive edge of clock
Q2 => data_r(n + DDR_DATA_WIDTH), -- 1-bit output for negative edge of clock
C => read_clk, -- 1-bit clock input
CE => read_en, -- 1-bit clock enable input
D => part_data(n), -- 1-bit DDR data input
R => '0', -- 1-bit reset
S => '0' -- 1-bit set
);
end generate;
data_sample_stage:
process (sys_clk0)
begin
if falling_edge(sys_clk0) then
data_reg_r <= data_r;
end if;
end process;
misc_flags_and_data_out:
process (sys_rst, sys_clk0)
variable p : unsigned(3 downto 0);
begin
if sys_rst = '1' then
p := (others => '0');
read_en <= '0';
sdr_data_vld <= '0';
sdr_data_req_w <= '0';
sdr_data_req_r <= '0';
elsif rising_edge(sys_clk0) then
sdr_data_r <= data_reg_r;
if p(3) = '1' then
u_tag_rd <= u_tag_pipe(4);
end if;
if phy_ctrl.we = '1' then
u_tag_wr <= u_tag_pipe(0);
end if;
sdr_data_req_w <= phy_ctrl.we;
sdr_data_req_r <= phy_ctrl.re;
sdr_data_vld <= p(3);
read_en <= p(1);
if phy_ctrl.re = '1' then
p := p(p'left-1 downto 0) & '1';
else
p := p(p'left-1 downto 0) & '0';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
end tech;
+111
View File
@@ -0,0 +1,111 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: Dual-ported register file with asynchrous read
-- Copyright (C) 2007 J. Ahrensfeld
-- This library 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 library 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 library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-- For questions and ideas, please contact the author at jens@jayfield.org
-----------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use work.fifo_ctrl_pkg.all;
entity fifo_sync is
Generic (
addr_width : natural := 4;
data_width : natural := 8;
almost_full_thresh : integer := 12;
almost_empty_thresh : integer := 4
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
we : in STD_LOGIC;
re : in STD_LOGIC;
fifo_full : out STD_LOGIC;
fifo_empty : out STD_LOGIC;
fifo_afull : out STD_LOGIC;
fifo_aempty : out STD_LOGIC;
data_w : in unsigned (data_width-1 downto 0);
data_r : out unsigned (data_width-1 downto 0)
);
end fifo_sync;
architecture Behavioral of fifo_sync is
signal mem_we : STD_LOGIC;
signal ptr_w : unsigned (addr_width-1 downto 0);
signal ptr_r : unsigned (addr_width-1 downto 0);
signal full : STD_LOGIC;
signal empty : STD_LOGIC;
signal almost_full : STD_LOGIC;
signal almost_empty : STD_LOGIC;
begin
mem_we <= we;
fifo_full <= full;
fifo_empty <= empty;
fifo_afull <= almost_full;
fifo_aempty <= almost_empty;
inst_sync_fifo_ctrl: entity work.sync_fifo_ctrl
GENERIC MAP
(
addr_width => addr_width,
almost_full_thresh => almost_full_thresh,
almost_empty_thresh => almost_empty_thresh
)
PORT MAP
(
rst => rst,
clk => clk,
we => we,
re => re,
ptr_w => ptr_w,
ptr_r => ptr_r,
fifo_full => full,
fifo_empty => empty,
fifo_afull => almost_full,
fifo_aempty => almost_empty
);
inst_dpram_1w1r: entity work.dpram_1w1r_dist
GENERIC MAP (
addr_width => addr_width,
data_width => data_width
)
PORT MAP(
clka => clk,
clkb => clk,
en_a => '1',
en_b => '1',
we_a => mem_we,
addr_a => ptr_w,
addr_b => ptr_r,
din_a => data_w,
dout_b => data_r
);
end Behavioral;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,111 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: Reset generator (Virtex-4 specific)
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
Library UNISIM;
use UNISIM.vcomponents.all;
entity reset is
port
(
clk : in std_logic;
rst_in : in std_logic;
rst_out : out std_logic
);
end;
architecture tech of reset is
signal rst : std_logic;
signal shift_pipe : std_logic_vector(3 downto 0);
attribute KEEP : string;
attribute KEEP of shift_pipe : signal is "TRUE";
begin
rst <= shift_pipe(0);
bufg_reset: bufg
port map
(
o => rst_out,
i => rst
);
fdp0: fdp
generic map
(
init => '1'
)
port map
(
d => rst_in,
c => clk,
pre => '0',
q => shift_pipe(3)
);
fdp1: fdp
generic map
(
init => '1'
)
port map
(
d => shift_pipe(3),
c => clk,
pre => '0',
q => shift_pipe(2)
);
fdp2: fdp
generic map
(
init => '1'
)
port map
(
d => shift_pipe(2),
c => clk,
pre => '0',
q => shift_pipe(1)
);
fdp3: fdp
generic map
(
init => '1'
)
port map
(
d => shift_pipe(1),
c => clk,
pre => '0',
q => shift_pipe(0)
);
end tech;
+269
View File
@@ -0,0 +1,269 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: SDRAM command controller
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
entity sdram_cmd is
Generic (BL : natural := 2);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
enable : in STD_LOGIC;
u_tag_in : in user_tag_t;
u_tag_out : out user_tag_t;
phy_ctrl : out phy_ctrl_t;
cmd : in sdr_cmd_t;
cmd_we : in STD_LOGIC;
cmd_ack : out STD_LOGIC;
col_addr : in col_addr_t;
mode_word : in mode_word_t;
sdr_cmd_ctrl : out sdr_cmd_lines_t;
sdr_addr : out sdr_addr_t;
sdr_ba : out sdr_ba_t
);
end sdram_cmd;
architecture behaviour of sdram_cmd is
signal st_sdr, st_sdr_next : sdr_state_t;
signal cc_preset : natural range 0 to 10;
signal cc_load_en : std_logic;
signal cycle_finished : std_logic;
signal burst_preset : natural range 0 to 3;
signal burst_load_en : std_logic;
signal burst_finished : std_logic;
begin
u_tag_out <= u_tag_in;
------------------------------------------------------------------------------------------
fsm_sdr_state:
process (st_sdr, cmd, cmd_we, cycle_finished, burst_finished, mode_word, enable, col_addr)
begin
st_sdr_next <= st_sdr;
sdr_cmd_ctrl <= COMMAND(SD_NOP);
cc_load_en <= '0';
cc_preset <= TIMING(cmd);
burst_load_en <= '0';
cmd_ack <= '0';
burst_preset <= BL/2-1;
phy_ctrl.re <= '0';
phy_ctrl.drive_en <= '0';
phy_ctrl.we <= '0';
phy_ctrl.utag_we <= '0';
sdr_addr <= mode_word(sdr_addr_t'left downto sdr_addr_t'right);
sdr_ba <= mode_word(mode_word_t'left downto mode_word_t'left-1);
case st_sdr is
when PWR_DOWN =>
sdr_cmd_ctrl <= COMMAND(SD_DESELECT);
if enable = '1' then
st_sdr_next <= IDLE;
end if;
when PRECHARGE =>
if cycle_finished = '1' then
st_sdr_next <= IDLE;
end if;
when MODE =>
if cycle_finished = '1' then
st_sdr_next <= IDLE;
end if;
when IDLE =>
if cmd_we = '1' then
cmd_ack <= '1';
cc_load_en <= '1';
cc_preset <= TIMING(cmd);
sdr_cmd_ctrl <= COMMAND(cmd);
case cmd is
when SD_PRE =>
st_sdr_next <= PRECHARGE;
sdr_addr(BIT_PRE_ALL) <= mode_word(BIT_PRE_ALL);
when SD_LMR =>
st_sdr_next <= MODE;
when SD_ACT =>
st_sdr_next <= ROW_ACT;
when SD_AR =>
st_sdr_next <= AUTO_REF;
when others => null;
end case;
end if;
when ROW_ACT =>
if cycle_finished = '1' then
if cmd_we = '1' then
cmd_ack <= '1';
burst_load_en <= '1';
cc_load_en <= '1';
cc_preset <= TIMING(cmd);
sdr_cmd_ctrl <= COMMAND(cmd);
case cmd is
when SD_PRE =>
st_sdr_next <= PRECHARGE;
when SD_READ =>
phy_ctrl.utag_we <= '1';
st_sdr_next <= READ;
sdr_addr(col_addr_t'range) <= col_addr;
when SD_WRITE =>
phy_ctrl.utag_we <= '1';
phy_ctrl.drive_en <= '1';
st_sdr_next <= WRITE;
sdr_addr(col_addr_t'range) <= col_addr;
when others => null;
end case;
end if;
end if;
when WRITE =>
phy_ctrl.drive_en <= '1';
phy_ctrl.we <= '1';
if burst_finished = '1' then
if cmd_we = '1' and cmd = SD_WRITE then
sdr_addr(col_addr_t'range) <= col_addr;
cmd_ack <= '1';
burst_load_en <= '1';
sdr_cmd_ctrl <= COMMAND(cmd);
phy_ctrl.utag_we <= '1';
else
phy_ctrl.drive_en <= '0';
cc_load_en <= '1';
cc_preset <= TIMING(SD_WRITE)+1;
st_sdr_next <= ROW_ACT;
end if;
end if;
when READ =>
phy_ctrl.re <= '1';
if burst_finished = '1' then
if cmd_we = '1' and cmd = SD_READ then
sdr_addr(col_addr_t'range) <= col_addr;
cmd_ack <= '1';
burst_load_en <= '1';
sdr_cmd_ctrl <= COMMAND(cmd);
phy_ctrl.utag_we <= '1';
else
cc_load_en <= '1';
cc_preset <= TIMING(SD_READ);
st_sdr_next <= ROW_ACT;
end if;
end if;
when WRITE_A => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when READ_A => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when BURST_STOP => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when SELF_REF => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when PRE_PWR_DOWN => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when ACT_PWR_DOWN => -- not implemented yet
cmd_ack <= '1';
st_sdr_next <= IDLE;
when AUTO_REF =>
if cycle_finished = '1' then
st_sdr_next <= IDLE;
end if;
when others =>
st_sdr_next <= IDLE;
end case;
end process;
fsm_sdr_state_next:
process (rst, clk)
begin
if rst = '1' then
st_sdr <= PWR_DOWN;
elsif rising_edge(clk) then
st_sdr <= st_sdr_next;
end if;
end process;
------------------------------------------------------------------------------------------
cycle_counter:
process (rst, clk)
variable cycle_cnt : natural range 0 to 10;
begin
if rst = '1' then
cycle_cnt := 0;
cycle_finished <= '0';
elsif rising_edge(clk) then
cycle_finished <= '0';
if cc_load_en = '1' then
cycle_cnt := cc_preset;
elsif cycle_cnt /= 0 then
cycle_cnt := cycle_cnt - 1;
else
cycle_finished <= '1';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
burst_counter:
process (rst, clk)
variable burst_cnt : natural range 0 to 3;
begin
if rst = '1' then
burst_cnt := 0;
elsif rising_edge(clk) then
burst_finished <= '0';
if burst_load_en = '1' then
burst_cnt := burst_preset;
elsif burst_cnt /= 0 then
burst_cnt := burst_cnt - 1;
end if;
if burst_cnt = 0 then
burst_finished <= '1';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
end behaviour;
@@ -0,0 +1,74 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: User SDRAM component adjustments
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
package sdram_config is
constant DDR_DATA_WIDTH : positive := 16; -- External DDR-SDRAM Module data bus width
constant DDR_ADDR_WIDTH : positive := 13; -- number of address lines to DDR-SDRAM Device/Module
constant DDR_BANK_WIDTH : positive := 2; -- Number of BANK address lines of external DDR-SDRAM
constant DDR_ROW_ADDR_WIDTH : positive := 13; --
constant DDR_COL_ADDR_WIDTH : positive := 9; --
constant LMR_REG_BASE : natural := 0;
constant LMR_REG_EXTENDED : natural := 1;
constant LMR_OP_NORMAL : natural := 0;
constant LMR_OP_RES_DLL : natural := 2;
constant LMR_BT_SEQ : natural := 0;
constant LMR_BT_ILVD : natural := 1;
constant LMR_BL2 : natural := 1;
constant LMR_BL4 : natural := 2;
constant LMR_BL8 : natural := 3;
constant LMR_CL2 : natural := 2;
constant LMR_CL3 : natural := 3;
constant LMR_CL2_5 : natural := 6;
-- DDR SDRAM Hardware defined constants
constant BIT_AUTO_PRE : positive := 10; -- bit-position in column address for auto precharge (see Data Sheet)
constant BIT_PRE_ALL : positive := 10; -- bit-position in column address for precharge all (see Data Sheet)
constant ENABLE_PRE_ALL : std_logic := '1';
constant ENABLE_AUTO_PRE : std_logic := '0';
-- DDR-SDR TIMING constants ------------------------------------------------------------------
-- After REFRESH_CLOCKS a refresh cycle is necessary, 64ms / 8192 = max every 7.8125 us refesh
constant REFRESH_INTERVAL : real := 7.8125; -- us
-- These values are for your SDRAM part (see datasheet)
constant TCAS : positive := 2; -- CAS latency [clocks]
constant TRP : positive := 2; -- precharge command period
constant TRAS : positive := 4; -- active to precharge delay
constant TRFC : positive := 8; -- auto refresh command period
constant TMRD : positive := 2; -- load mode register command cylce time
constant TRCD : positive := 2; -- active to read or write delay !
constant TWR : positive := 2; -- write recovery time
constant PWR_UP_WAIT : natural := 1; -- µs
subtype user_tag_t is unsigned(3 downto 0);
----------------------------------------------------------------------------------------------
end sdram_config;
+487
View File
@@ -0,0 +1,487 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: SDRAM main controller and user I/F
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity sdram_ctrl is
Generic
(
f_sysclk : natural := 100E6;
BL : natural := 2
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
u_busy : out STD_LOGIC;
u_tag_in : in user_tag_t;
u_tag_out : out user_tag_t;
u_addr : in user_addr_t;
u_cmd : in user_cmd_t;
u_cmd_we : in STD_LOGIC;
col_addr : out col_addr_t;
sdr_cmd_busy : in STD_LOGIC;
sdr_cmd : out sdr_cmd_t;
sdr_cmd_we : out STD_LOGIC;
sdr_mode : out mode_word_t;
sdr_cke : out STD_LOGIC
);
end sdram_ctrl;
architecture behaviour of sdram_ctrl is
constant LMR_BURST_LEN : natural := NextExpBaseTwo(BL);
type ctrl_state_t is (RESET, POWER_WAIT, INIT, INIT_WAIT, USER_READY, USER_WRITE_PRE, USER_WRITE_ACT, USER_WRITE, USER_READ_PRE, USER_READ_ACT, USER_READ, REFRESH);
signal st_ctrl, st_ctrl_next : ctrl_state_t;
constant PWR_UP_CLOCK_INTERVAL : natural := PWR_UP_WAIT*(f_sysclk/1E6);
signal pwr_up_cnt : natural range 0 to PWR_UP_CLOCK_INTERVAL-1;
signal pwr_up_cnt_rst : std_logic;
signal pwr_up_finished : std_logic;
signal cycle_cnt : natural range 0 to 255;
signal cc_preset : natural range 0 to 255;
signal cc_load_en : std_logic;
signal cycle_finished : std_logic;
signal seq_cnt : natural range 0 to 31;
signal seq_rst_en : std_logic;
signal seq_cnt_en : std_logic;
constant REFRESH_CLOCK_INTERVAL : natural := natural(REFRESH_INTERVAL*real(f_sysclk)/1.0E6);
signal refresh_cnt : natural range 0 to REFRESH_CLOCK_INTERVAL-1;
signal refresh_request : std_logic;
signal refresh_cnt_rst : std_logic;
signal addr_reg_load_en : std_logic;
signal u_tag_reg : user_tag_t;
signal bank_addr_reg : bank_addr_t;
signal row_addr_reg : row_addr_t;
signal col_addr_reg : col_addr_t;
signal u_bank_addr : bank_addr_t;
signal u_row_addr : row_addr_t;
signal u_col_addr : col_addr_t;
signal act_request : std_logic;
signal act_request_set : std_logic;
signal act_request_clr : std_logic;
type init_seq_rom_t is array (0 to 14) of init_seq_t;
constant init_seq_rom : init_seq_rom_t :=
(
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_PRE,
mode_word => "000010000000000",
wait_cycle => 0
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_LMR,
mode_word => to_unsigned(LMR_REG_EXTENDED, 2) & "0000000000010",
wait_cycle => 0
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_LMR,
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_RES_DLL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
wait_cycle => 200
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_PRE,
mode_word => "000010000000000",
wait_cycle => 0
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_AR,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_AR,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
),
(
cmd => SD_LMR,
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_NORMAL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
wait_cycle => 200
),
(
cmd => SD_NOP,
mode_word => (others => '0'),
wait_cycle => 0
)
);
begin
u_row_addr <= u_addr(user_addr_t'left downto user_addr_t'left-row_addr_t'length+1);
u_bank_addr <= u_addr(user_addr_t'left-row_addr_t'length downto user_addr_t'left-row_addr_t'length-bank_addr_t'length+1);
u_col_addr <= u_addr(user_addr_t'left-row_addr_t'length-bank_addr_t'length downto 0);
------------------------------------------------------------------------------------------
fsm_ctrl_state:
process (st_ctrl, u_tag_in, u_tag_reg, u_cmd, u_cmd_we, sdr_cmd_busy, pwr_up_finished, seq_cnt, cycle_finished, u_bank_addr, u_row_addr, bank_addr_reg, row_addr_reg, u_col_addr, col_addr_reg, refresh_request, act_request)
begin
u_busy <= '1';
pwr_up_cnt_rst <= '0';
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
cc_load_en <= '0';
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
sdr_cmd_we <= '0';
sdr_mode <= bank_addr_reg & row_addr_reg;
col_addr <= col_addr_reg;
sdr_cke <= '1';
seq_cnt_en <= '0';
seq_rst_en <= '0';
addr_reg_load_en <= '0';
refresh_cnt_rst <= '0';
act_request_set <= '0';
act_request_clr <= '0';
u_tag_out <= u_tag_reg;
st_ctrl_next <= st_ctrl;
case st_ctrl is
when RESET =>
sdr_cke <= '0';
pwr_up_cnt_rst <= '1';
st_ctrl_next <= POWER_WAIT;
when POWER_WAIT =>
sdr_cke <= '0';
if pwr_up_finished = '1' then
seq_rst_en <= '1';
st_ctrl_next <= INIT;
end if;
when INIT =>
sdr_mode <= init_seq_rom(seq_cnt).mode_word;
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
if seq_cnt = init_seq_rom_t'high then
act_request_set <= '1';
refresh_cnt_rst <= '1';
st_ctrl_next <= USER_READY;
elsif sdr_cmd_busy = '0' then
cc_load_en <= '1';
sdr_cmd_we <= '1';
st_ctrl_next <= INIT_WAIT;
end if;
when INIT_WAIT =>
if sdr_cmd_busy = '0' and cycle_finished = '1' then
seq_cnt_en <= '1';
st_ctrl_next <= INIT;
end if;
when USER_READY =>
if sdr_cmd_busy = '0' then
if refresh_request = '1' then
sdr_mode(BIT_PRE_ALL) <= '1';
sdr_cmd_we <= '1';
sdr_cmd <= SD_PRE;
st_ctrl_next <= REFRESH;
else
u_busy <= '0';
if u_cmd_we = '1' then
case u_cmd is
when UCMD_NOP =>
sdr_cmd <= SD_NOP;
when UCMD_LMR =>
sdr_cmd <= SD_NOP;
when UCMD_WRITE =>
col_addr <= u_col_addr;
u_tag_out <= u_tag_in;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
addr_reg_load_en <= '1';
act_request_clr <= '1';
sdr_cmd <= SD_WRITE;
if (u_row_addr /= row_addr_reg) or act_request = '1' then
st_ctrl_next <= USER_WRITE_PRE;
elsif (u_bank_addr /= bank_addr_reg) then
if ENABLE_PRE_ALL = '1' then
st_ctrl_next <= USER_WRITE_ACT;
else
st_ctrl_next <= USER_WRITE_PRE;
end if;
elsif sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
else
st_ctrl_next <= USER_WRITE;
end if;
when UCMD_READ =>
col_addr <= u_col_addr;
u_tag_out <= u_tag_in;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
addr_reg_load_en <= '1';
act_request_clr <= '1';
sdr_cmd <= SD_READ;
if (u_row_addr /= row_addr_reg) or act_request = '1' then
st_ctrl_next <= USER_READ_PRE;
elsif (u_bank_addr /= bank_addr_reg) then
if ENABLE_PRE_ALL = '1' then
st_ctrl_next <= USER_READ_ACT;
else
st_ctrl_next <= USER_READ_PRE;
end if;
elsif sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
else
st_ctrl_next <= USER_READ;
end if;
when others => null;
end case;
end if;
end if;
end if;
when USER_WRITE_PRE =>
sdr_cmd <= SD_PRE;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_WRITE_ACT;
end if;
when USER_WRITE_ACT =>
sdr_cmd <= SD_ACT;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_WRITE;
end if;
when USER_WRITE =>
sdr_cmd <= SD_WRITE;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
end if;
when USER_READ_PRE =>
sdr_cmd <= SD_PRE;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READ_ACT;
end if;
when USER_READ_ACT =>
sdr_cmd <= SD_ACT;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READ;
end if;
when USER_READ =>
sdr_cmd <= SD_READ;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
end if;
when REFRESH =>
sdr_cmd <= SD_AR;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
refresh_cnt_rst <= '1';
act_request_set <= '1';
end if;
when others =>
st_ctrl_next <= RESET;
end case;
end process;
fsm_ctrl_state_next:
process (rst, clk)
begin
if rst = '1' then
st_ctrl <= RESET;
elsif rising_edge(clk) then
st_ctrl <= st_ctrl_next;
end if;
end process;
------------------------------------------------------------------------------------------
act_request_register:
process (rst, clk)
begin
if rst = '1' then
act_request <= '1';
elsif rising_edge(clk) then
if act_request_set = '1' then
act_request <= '1';
elsif act_request_clr = '1' then
act_request <= '0';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
user_addr_register:
process (rst, clk)
begin
if rst = '1' then
bank_addr_reg <= (others => '0');
row_addr_reg <= (others => '0');
col_addr_reg <= (others => '0');
u_tag_reg <= (others => '0');
elsif rising_edge(clk) then
if addr_reg_load_en = '1' then
bank_addr_reg <= u_bank_addr;
row_addr_reg <= u_row_addr;
col_addr_reg <= u_col_addr;
u_tag_reg <= u_tag_in;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
power_up_counter:
process (rst, clk)
begin
if rst = '1' then
pwr_up_cnt <= 0;
pwr_up_finished <= '0';
elsif rising_edge(clk) then
pwr_up_finished <= '0';
if pwr_up_cnt_rst = '1' then
pwr_up_cnt <= PWR_UP_CLOCK_INTERVAL-1;
else
if pwr_up_cnt /= 0 then
pwr_up_cnt <= pwr_up_cnt - 1;
else
pwr_up_finished <= '1';
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
refresh_counter:
process (rst, clk)
begin
if rst = '1' then
refresh_cnt <= 0;
refresh_request <= '0';
elsif rising_edge(clk) then
refresh_request <= '0';
if refresh_cnt_rst = '1' then
refresh_cnt <= REFRESH_CLOCK_INTERVAL-1;
else
if refresh_cnt /= 0 then
refresh_cnt <= refresh_cnt - 1;
else
refresh_request <= '1';
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
cycle_counter:
process (rst, clk)
begin
if rst = '1' then
cycle_cnt <= 0;
cycle_finished <= '0';
elsif rising_edge(clk) then
cycle_finished <= '0';
if cc_load_en = '1' then
cycle_cnt <= cc_preset;
elsif cycle_cnt /= 0 then
cycle_cnt <= cycle_cnt - 1;
else
cycle_finished <= '1';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
seq_counter:
process (rst, clk)
begin
if rst = '1' then
seq_cnt <= 0;
elsif rising_edge(clk) then
if seq_rst_en = '1' then
seq_cnt <= 0;
elsif seq_cnt_en = '1' then
if seq_cnt /= init_seq_rom_t'high then
seq_cnt <= seq_cnt + 1;
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
end behaviour;
@@ -0,0 +1,277 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
entity sdram_ctrl_frontend is
Generic
(
BL : natural := 2;
f_sysclk : natural := 100E6;
read_phaseshift : integer := 0;
fifo_depth : integer := 4
);
Port
(
sys_rst_in : in STD_LOGIC;
sys_clk_in : in STD_LOGIC;
sys_rst_out : out STD_LOGIC;
sys_clk_out : out STD_LOGIC;
sys_clk_fb : in STD_LOGIC;
-- User interface
busy : out STD_LOGIC;
en : in STD_LOGIC;
r_wn : in STD_LOGIC;
be : in unsigned(SDR_DM_WIDTH-1 downto 0);
addr : in user_addr_t;
din : in unsigned(SDR_DATA_WIDTH-1 downto 0);
dout : out unsigned(SDR_DATA_WIDTH-1 downto 0);
dout_re : in STD_LOGIC;
dout_vld : out STD_LOGIC;
-- SDRAM signals
sd_clk_p : out STD_LOGIC;
sd_clk_n : out STD_LOGIC;
sd_cke : out STD_LOGIC;
sd_cs_n : out STD_LOGIC;
sd_cas_n : out STD_LOGIC;
sd_ras_n : out STD_LOGIC;
sd_we_n : out STD_LOGIC;
sd_addr : out sdr_addr_t;
sd_ba : out sdr_ba_t;
sd_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
sd_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
sd_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0)
);
end sdram_ctrl_frontend;
architecture struct of sdram_ctrl_frontend is
-- Number of user data words for simulation
signal rst_out : std_logic;
signal clk_out : std_logic;
signal u_addr : user_addr_t;
signal u_tag_in : user_tag_t;
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t;
signal u_cmd_we : std_logic;
signal u_busy : std_logic;
signal u_data_w : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal u_dm : unsigned(SDR_DM_WIDTH-1 downto 0);
signal u_data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
constant CAT_FIFO_WIDTH : integer := user_cmd_t'length + user_tag_t'length + DDR_ROW_ADDR_WIDTH + DDR_BANK_WIDTH + DDR_COL_ADDR_WIDTH;
signal cat_fifo_din : unsigned(CAT_FIFO_WIDTH-1 downto 0);
signal cat_fifo_dout : unsigned(CAT_FIFO_WIDTH-1 downto 0);
signal cat_fifo_re : std_logic;
signal cat_fifo_we : std_logic;
signal cat_fifo_full : std_logic;
signal cat_fifo_empty : std_logic;
-- signal cat_fifo_almost_full : std_logic;
-- signal cat_fifo_almost_empty : std_logic;
signal write_fifo_din : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
signal write_fifo_dout : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
signal write_fifo_re : std_logic;
signal write_fifo_we : std_logic;
signal write_fifo_full : std_logic;
signal write_fifo_empty : std_logic;
-- signal write_fifo_almost_full : std_logic;
-- signal write_fifo_almost_empty : std_logic;
signal read_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal read_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal read_fifo_re : std_logic;
signal read_fifo_we : std_logic;
signal read_fifo_full : std_logic;
signal read_fifo_empty : std_logic;
-- signal read_fifo_almost_full : std_logic;
-- signal read_fifo_almost_empty : std_logic;
alias cmd_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
alias tag_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
alias addr_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
alias cmd_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
alias tag_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
alias addr_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
alias write_fifo_dm_in is write_fifo_din(write_fifo_din'length-1 downto write_fifo_din'length-SDR_DM_WIDTH);
alias write_fifo_data_in is write_fifo_din(write_fifo_din'length-SDR_DM_WIDTH-1 downto 0);
alias write_fifo_dm_out is write_fifo_dout(write_fifo_dout'length-1 downto write_fifo_dout'length-SDR_DM_WIDTH);
alias write_fifo_data_out is write_fifo_dout(write_fifo_dout'length-SDR_DM_WIDTH-1 downto 0);
begin
-- Instantiate synchronous FIFO
inst_cat_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => fifo_depth,
data_width => CAT_FIFO_WIDTH
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => cat_fifo_we,
re => cat_fifo_re,
fifo_full => cat_fifo_full,
fifo_empty => cat_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cat_fifo_din,
data_r => cat_fifo_dout
);
-- Instantiate synchronous FIFO
inst_write_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => fifo_depth,
data_width => 2*DDR_DATA_WIDTH + SDR_DM_WIDTH
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => write_fifo_we,
re => write_fifo_re,
fifo_full => write_fifo_full,
fifo_empty => write_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => write_fifo_din,
data_r => write_fifo_dout
);
-- Instantiate synchronous FIFO
inst_read_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => fifo_depth,
data_width => 2*DDR_DATA_WIDTH
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => read_fifo_we,
re => read_fifo_re,
fifo_full => read_fifo_full,
fifo_empty => read_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => read_fifo_din,
data_r => read_fifo_dout
);
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BL,
read_phaseshift => read_phaseshift,
f_sysclk => f_sysclk
)
Port map
(
sys_rst_in => sys_rst_in,
sys_clk_in => sys_clk_in,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => sys_clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => open,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => sd_clk_p,
sd_clk_n => sd_clk_n,
sd_cke => sd_cke,
sd_cs_n => sd_cs_n,
sd_cas_n => sd_cas_n,
sd_ras_n => sd_ras_n,
sd_we_n => sd_we_n,
sd_addr => sd_addr,
sd_ba => sd_ba,
sd_dm => sd_dm,
sd_dqs => sd_dqs,
sd_data => sd_data
);
------------------------------------------------------------------------------------------
sys_rst_out <= rst_out;
sys_clk_out <= clk_out;
busy <= cat_fifo_full or write_fifo_full or read_fifo_full;
write_fifo_we <= en and not r_wn and not write_fifo_full and not cat_fifo_full and not read_fifo_full;
write_fifo_data_in <= din;
write_fifo_dm_in <= not be;
cat_fifo_we <= en and not cat_fifo_full and not write_fifo_full and not read_fifo_full;
cmd_fifo_in <= UCMD_WRITE when r_wn = '0' else UCMD_READ;
addr_fifo_in <= addr;
tag_fifo_in <= (others=>'0');
dout <= read_fifo_dout;
dout_vld <= not read_fifo_empty;
u_cmd_we <= (not cat_fifo_empty) and (not u_busy);
u_cmd <= cmd_fifo_out;
u_addr <= addr_fifo_out;
u_dm <= write_fifo_dm_out;
u_tag_in <= tag_fifo_out;
write_fifo_re <= u_req_wr and (not write_fifo_empty);
cat_fifo_re <= u_cmd_we;
u_data_w <= write_fifo_data_out;
read_fifo_re <= (not read_fifo_empty) and dout_re;
read_fifo_we <= u_data_vld;
read_fifo_din <= u_data_r;
end architecture struct;
@@ -0,0 +1,285 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: Top-level put all together
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
entity sdram_ctrl_top is
Generic
(
BL : natural := 2;
f_sysclk : natural := 100E6;
read_phaseshift : integer := 0
);
Port
(
sys_rst_in : in STD_LOGIC;
sys_clk_in : in STD_LOGIC;
sys_rst_out : out STD_LOGIC;
sys_clk_out : out STD_LOGIC;
sys_clk_fb : in STD_LOGIC;
-- User interface
u_data_vld : out STD_LOGIC;
u_data_req_w : out STD_LOGIC;
u_data_req_r : out STD_LOGIC;
u_busy : out STD_LOGIC;
u_tag_in : in user_tag_t;
u_tag_rd : out user_tag_t;
u_tag_wr : out user_tag_t;
u_addr : in user_addr_t;
u_cmd : in user_cmd_t;
u_cmd_we : in STD_LOGIC;
u_data_wr : in unsigned(SDR_DATA_WIDTH-1 downto 0);
u_dm : in unsigned(SDR_DM_WIDTH-1 downto 0);
u_data_rd : out unsigned(SDR_DATA_WIDTH-1 downto 0);
-- SDRAM signals
sd_clk_p : out STD_LOGIC;
sd_clk_n : out STD_LOGIC;
sd_cke : out STD_LOGIC;
sd_cs_n : out STD_LOGIC;
sd_cas_n : out STD_LOGIC;
sd_ras_n : out STD_LOGIC;
sd_we_n : out STD_LOGIC;
sd_addr : out sdr_addr_t;
sd_ba : out sdr_ba_t;
sd_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
sd_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
sd_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0)
);
end sdram_ctrl_top;
architecture rtl of sdram_ctrl_top is
signal clk0 : std_logic;
signal clk270 : std_logic;
signal read_clk270 : std_logic;
signal phy_ctrl : phy_ctrl_t;
signal u_tag : user_tag_t;
signal sd_cmd_in : sdr_cmd_t;
signal sd_cmd : sdr_cmd_t;
signal sd_cmd_we : std_logic;
signal cmd_ctrl : sdr_cmd_lines_t;
signal cke : std_logic;
signal ba : unsigned(DDR_BANK_WIDTH-1 downto 0);
signal addr : unsigned(DDR_ADDR_WIDTH-1 downto 0);
-- Clock generator
signal cg_rst : std_logic;
signal cg_read_clk0 : std_logic;
signal cg_read_clk270 : std_logic;
signal cg_sys_clk0 : std_logic;
signal cg_sys_clk270 : std_logic;
signal cg_locked : std_logic;
signal cg_error : std_logic;
signal ctrl_rst : std_logic;
signal part_ctrl : part_ctrl_t;
-- SD command FIFO
constant CMD_FIFO_ADDR_WIDTH : positive := 2;
constant CMD_FIFO_DATA_WIDTH : positive := user_tag_t'length + 4 + mode_word_t'length + col_addr_t'length;
signal cmd_fifo_din : unsigned(CMD_FIFO_DATA_WIDTH-1 downto 0);
signal cmd_fifo_dout : unsigned(CMD_FIFO_DATA_WIDTH-1 downto 0);
signal cmd_fifo_re : std_logic;
signal cmd_fifo_we : std_logic;
signal cmd_fifo_full : std_logic;
signal cmd_fifo_empty : std_logic;
alias tag_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length);
alias cmd_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4);
alias mode_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length);
alias col_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length-1 downto 0);
alias tag_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length);
alias cmd_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4);
alias mode_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length);
alias col_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length-1 downto 0);
begin
---------------------------------
clk0 <= cg_sys_clk0;
clk270 <= cg_sys_clk270;
read_clk270 <= cg_read_clk270;
cg_rst <= not cg_locked;
---------------------------------
sys_clk_out <= cg_sys_clk0;
sys_rst_out <= ctrl_rst;
---------------------------------
part_ctrl.cmd <= cmd_ctrl;
part_ctrl.ba <= ba;
part_ctrl.addr <= addr;
part_ctrl.cke <= cke;
---------------------------------
sd_cmd_we <= not cmd_fifo_empty;
cmd_fifo_in <= to_unsigned(sd_cmd_in, 4);
sd_cmd <= sdr_cmd_t(to_integer(cmd_fifo_out));
---------------------------------
inst_reset: entity work.reset
port map
(
clk => clk0,
rst_in => cg_rst,
rst_out => ctrl_rst
);
inst_clockgen : entity work.clockgen
generic map
(
read_phaseshift => read_phaseshift,
frequency_hz => f_sysclk
)
port map
(
rst => sys_rst_in,
clk_in => sys_clk_in,
clk_fb_in => sys_clk_fb,
read_clk0_out => cg_read_clk0,
read_clk270_out => cg_read_clk270,
sys_clk0_out => cg_sys_clk0,
sys_clk270_out => cg_sys_clk270,
locked_out => cg_locked,
error_out => cg_error
);
-- Main controller
inst_sdram_ctrl : entity work.sdram_ctrl
Generic map
(
f_sysclk => 100E6,
BL => BL
)
Port map
(
rst => ctrl_rst,
clk => clk0,
u_busy => u_busy,
u_tag_in => u_tag_in,
u_tag_out => tag_fifo_in,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_addr => u_addr,
sdr_cmd_busy => cmd_fifo_full,
sdr_cmd => sd_cmd_in,
sdr_cmd_we => cmd_fifo_we,
col_addr => col_fifo_in,
sdr_mode => mode_fifo_in,
sdr_cke => cke
);
-- Instantiate synchronous FIFO
inst_sd_cmd_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => CMD_FIFO_ADDR_WIDTH,
data_width => CMD_FIFO_DATA_WIDTH,
almost_full_thresh => 2**(CMD_FIFO_ADDR_WIDTH-1),
almost_empty_thresh => 2**(CMD_FIFO_ADDR_WIDTH-1)
)
PORT MAP
(
rst => ctrl_rst,
clk => clk0,
we => cmd_fifo_we,
re => cmd_fifo_re,
fifo_full => cmd_fifo_full,
fifo_empty => cmd_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cmd_fifo_din,
data_r => cmd_fifo_dout
);
-- DDR SDRAM command fsm
inst_sdram_cmd : entity work.sdram_cmd
Generic map
(
BL => BL
)
Port map
(
rst => ctrl_rst,
clk => clk0,
u_tag_in => tag_fifo_out,
u_tag_out => u_tag,
phy_ctrl => phy_ctrl,
enable => cke,
cmd => sd_cmd,
cmd_we => sd_cmd_we,
cmd_ack => cmd_fifo_re,
sdr_cmd_ctrl => cmd_ctrl,
col_addr => col_fifo_out,
mode_word => mode_fifo_out,
sdr_ba => ba,
sdr_addr => addr
);
-- DDR phy
inst_ddr_phy : entity work.ddr_phy
Port map
(
sys_rst => ctrl_rst,
sys_clk0 => clk0,
sys_clk270 => clk270,
u_tag_in => u_tag,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
read_clk => read_clk270,
phy_ctrl => phy_ctrl,
part_ctrl => part_ctrl,
sdr_data_req_w => u_data_req_w,
sdr_data_req_r => u_data_req_r,
sdr_data_w => u_data_wr,
sdr_dm => u_dm,
sdr_data_r => u_data_rd,
sdr_data_vld => u_data_vld,
part_clk_p => sd_clk_p,
part_clk_n => sd_clk_n,
part_addr => sd_addr,
part_ba => sd_ba,
part_dm => sd_dm,
part_dqs => sd_dqs,
part_data => sd_data,
part_cs_n => sd_cs_n,
part_we_n => sd_we_n,
part_cas_n => sd_cas_n,
part_ras_n => sd_ras_n,
part_cke => sd_cke
);
end architecture rtl;
+133
View File
@@ -0,0 +1,133 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: Type definitions
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use work.sdram_config.all;
package sdram_types is
-----------------------------------------------------------------------------------------
-- Table of Timing Parameters as a function of operation
-- Derived constants from sdram_config
constant DDR_DQS_WIDTH : positive := DDR_DATA_WIDTH / 8; -- Number of data strobe lines
constant DDR_DM_WIDTH : positive := DDR_DATA_WIDTH / 8; -- Number of Data Mask Lines
constant SDR_DATA_WIDTH : positive := 2*DDR_DATA_WIDTH; --
constant SDR_DM_WIDTH : positive := 2*DDR_DM_WIDTH; --
subtype user_cmd_t is unsigned(1 downto 0);
constant UCMD_NOP : user_cmd_t := "00";
constant UCMD_READ : user_cmd_t := "01";
constant UCMD_WRITE : user_cmd_t := "10";
constant UCMD_LMR : user_cmd_t := "11";
subtype sdr_cmd_t is natural range 0 to 9;
constant SD_DESELECT : sdr_cmd_t := 0;
constant SD_NOP : sdr_cmd_t := 1;
constant SD_LMR : sdr_cmd_t := 2;
constant SD_ACT : sdr_cmd_t := 3;
constant SD_READ : sdr_cmd_t := 4;
constant SD_WRITE : sdr_cmd_t := 5;
constant SD_PRE : sdr_cmd_t := 6;
constant SD_BST : sdr_cmd_t := 7;
constant SD_AR : sdr_cmd_t := 8;
constant SD_SR : sdr_cmd_t := 9;
type sdr_state_t is (PWR_DOWN, PRECHARGE, MODE, IDLE, ROW_ACT, WRITE, WRITE_A, READ, READ_A, BURST_STOP, SELF_REF, AUTO_REF, PRE_PWR_DOWN, ACT_PWR_DOWN);
subtype user_addr_t is unsigned(DDR_BANK_WIDTH+DDR_ROW_ADDR_WIDTH+DDR_COL_ADDR_WIDTH-1 downto 0);
subtype sdr_addr_t is unsigned(DDR_ADDR_WIDTH-1 downto 0);
subtype sdr_ba_t is unsigned(DDR_BANK_WIDTH-1 downto 0);
subtype mode_word_t is unsigned(DDR_ADDR_WIDTH+DDR_BANK_WIDTH-1 downto 0);
subtype bank_addr_t is unsigned(DDR_BANK_WIDTH-1 downto 0);
subtype row_addr_t is unsigned(DDR_ADDR_WIDTH-1 downto 0);
subtype col_addr_t is unsigned(8 downto 0);
subtype cycle_cnt_t is natural range 0 to 10;
type phy_ctrl_t is
record
drive_en : std_logic;
re : std_logic;
we : std_logic;
utag_we : std_logic;
end record phy_ctrl_t;
type sdr_cmd_lines_t is
record
cs_n : std_logic;
ras_n : std_logic;
cas_n : std_logic;
we_n : std_logic;
end record sdr_cmd_lines_t;
type part_ctrl_t is
record
cmd : sdr_cmd_lines_t;
ba : unsigned(DDR_BANK_WIDTH-1 downto 0);
addr : unsigned(DDR_ADDR_WIDTH-1 downto 0);
cke : std_logic;
end record part_ctrl_t;
type part_cmd_array_t is array (sdr_cmd_t) of sdr_cmd_lines_t;
constant COMMAND : part_cmd_array_t :=
-- command cs_n ras_qn cas_qn we_qn
( SD_DESELECT => ( '1', '1', '1', '1'),
SD_NOP => ( '0', '1', '1', '1'),
SD_LMR => ( '0', '0', '0', '0'),
SD_ACT => ( '0', '0', '1', '1'),
SD_READ => ( '0', '1', '0', '1'),
SD_WRITE => ( '0', '1', '0', '0'),
SD_PRE => ( '0', '0', '1', '0'),
SD_BST => ( '0', '1', '1', '0'),
SD_AR => ( '0', '0', '0', '1'),
SD_SR => ( '0', '0', '0', '1')
);
type part_timing_array_t is array (sdr_cmd_t) of cycle_cnt_t;
constant TIMING : part_timing_array_t :=
-- command cycle_cnt
( SD_DESELECT => ( 0 ),
SD_NOP => ( 0 ),
SD_LMR => ( TMRD-1 ),
SD_ACT => ( TRCD-1 ),
SD_READ => ( TCAS-1 ),
SD_WRITE => ( TWR-1 ),
SD_PRE => ( TRP-1 ),
SD_BST => ( 0 ),
SD_AR => ( TRFC-1 ),
SD_SR => ( TRFC-1 )
);
type init_seq_t is
record
cmd : sdr_cmd_t;
mode_word : mode_word_t;
wait_cycle : natural;
end record init_seq_t;
end sdram_types;
+332
View File
@@ -0,0 +1,332 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity tb_sdr_ctrl is
end;
architecture struct of tb_sdr_ctrl is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 8;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal u_addr_cnt_en : std_logic := '0';
signal u_addr_load : std_logic := '0';
signal u_addr_preset : user_addr_t := (others => '0');
signal u_addr_end : user_addr_t := (others => '0');
signal ref_data : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
type test_phase_t is (IDLE, PART_INIT, WRITE_SINGLE, WRITE_MULTI, READ_SINGLE, READ_MULTI, FINISHED);
signal test_phase : test_phase_t := IDLE;
type u_addr_mode_t is (MONOTONIC, RANDOM);
signal u_addr_mode : u_addr_mode_t := MONOTONIC;
signal cycle_cnt : natural := 1;
signal data_cnt : natural := 0;
signal efficiency : real := 0.0;
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
R_DATA_COMPARE:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_data_vld='1' then
if u_read_en = '1' then
assert (ref_data = u_data_r) report "Error on read!" severity failure;
end if;
for i in 0 to DDR_DATA_WIDTH/4-1 loop
ref_data((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_read_en = '0' then
last_data := (others => '0');
ref_data <= (others => '0');
end if;
end if;
end process;
W_DATA_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_req_wr = '1' then
for i in 0 to DDR_DATA_WIDTH/4-1 loop
u_data_w((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_write_en = '0' then
last_data := (others => '0');
u_data_w <= (others => '0');
end if;
end if;
end process;
ADDR_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_addr_load = '1' then
u_addr <= u_addr_preset;
elsif u_addr_cnt_en = '1' then
if u_addr_mode = MONOTONIC then
u_addr <= u_addr + BURST_LEN;
else
if u_addr(u_addr'left) = '1' then
if BURST_LEN = 2 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "10000000000010001010100";
elsif BURST_LEN = 4 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "1000000000010011010110";
elsif BURST_LEN = 8 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "100000000001011110100";
end if;
else
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)-1) <= u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)-1) & u_addr(u_addr'left);
end if;
end if;
end if;
end if;
end process;
performance_count:
process(clk_out)
begin
if rising_edge(clk_out) then
if u_write_en = '1' or u_read_en = '1' then
cycle_cnt <= cycle_cnt + 1;
if u_req_wr = '1' or u_req_rd = '1' then
data_cnt <= data_cnt + 1;
end if;
else
cycle_cnt <= 1;
data_cnt <= 0;
end if;
end if;
end process;
u_tag_in <= ("00" & u_write_en & u_read_en) when ((u_addr = X"333C98" or u_addr = X"000100") and u_cmd_we = '1') else "0000";
efficiency <= real(data_cnt)/real(cycle_cnt);
u_cmd_we <= (u_write_en or u_read_en) and (not u_busy);
u_addr_cnt_en <= '1' when (u_cmd_we = '1' and (u_addr /= u_addr_end)) else '0';
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait until rising_edge(clk_out) and u_busy='0';
wait for 137*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
u_addr_preset <= X"000000";
u_addr_end <= X"008000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_WRITE;
u_write_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
wait until rising_edge(clk_out) and u_req_wr='0';
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 1
u_addr_preset <= X"400000";
u_addr_end <= X"408000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_WRITE;
u_write_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
wait until rising_edge(clk_out) and u_req_wr='0';
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
u_addr_preset <= X"000000";
u_addr_end <= X"008000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_READ;
u_read_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 1
u_addr_preset <= X"400000";
u_addr_end <= X"408000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_READ;
u_read_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait;
end process;
end architecture struct;
@@ -0,0 +1,416 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
entity tb_sdr_ctrl_fifo is
end;
architecture struct of tb_sdr_ctrl_fifo is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 2;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal cmd_fifo_din : unsigned(25 downto 0) := (others => '0');
signal cmd_fifo_dout : unsigned(25 downto 0) := (others => '0');
signal cmd_fifo_re : std_logic := '0';
signal cmd_fifo_we : std_logic := '0';
signal cmd_fifo_full : std_logic := '0';
signal cmd_fifo_empty : std_logic := '0';
signal cmd_fifo_almost_full : std_logic := '0';
signal cmd_fifo_almost_empty : std_logic := '0';
signal write_fifo_din : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal write_fifo_dout : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal write_fifo_re : std_logic := '0';
signal write_fifo_we : std_logic := '0';
signal write_fifo_full : std_logic := '0';
signal write_fifo_empty : std_logic := '0';
signal write_fifo_almost_full : std_logic := '0';
signal write_fifo_almost_empty : std_logic := '0';
signal read_fifo_din : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal read_fifo_dout : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal read_fifo_re : std_logic := '0';
signal read_fifo_we : std_logic := '0';
signal read_fifo_full : std_logic := '0';
signal read_fifo_empty : std_logic := '0';
signal read_fifo_almost_full : std_logic := '0';
signal read_fifo_almost_empty : std_logic := '0';
signal write_start : std_logic := '1';
signal read_start : std_logic := '1';
alias cmd_fifo_in is cmd_fifo_din(25 downto 24);
alias addr_fifo_in is cmd_fifo_din(23 downto 0);
alias cmd_fifo_out is cmd_fifo_dout(25 downto 24);
alias addr_fifo_out is cmd_fifo_dout(23 downto 0);
begin
clk_fb <= part_clk_p after 1 ns;
-- Instantiate synchronous FIFO
inst_command_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 8,
data_width => 2+24
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => cmd_fifo_we,
re => cmd_fifo_re,
fifo_full => cmd_fifo_full,
fifo_empty => cmd_fifo_empty,
fifo_afull => cmd_fifo_almost_full,
fifo_aempty => cmd_fifo_almost_empty,
data_w => cmd_fifo_din,
data_r => cmd_fifo_dout
);
-- Instantiate synchronous FIFO
inst_write_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 8,
data_width => 2*DDR_DATA_WIDTH
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => write_fifo_we,
re => write_fifo_re,
fifo_full => write_fifo_full,
fifo_empty => write_fifo_empty,
fifo_afull => write_fifo_almost_full,
fifo_aempty => write_fifo_almost_empty,
data_w => write_fifo_din,
data_r => write_fifo_dout
);
-- Instantiate synchronous FIFO
inst_read_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 8,
data_width => 2*DDR_DATA_WIDTH
)
PORT MAP
(
rst => rst_out,
clk => clk_out,
we => read_fifo_we,
re => read_fifo_re,
fifo_full => read_fifo_full,
fifo_empty => read_fifo_empty,
fifo_afull => read_fifo_almost_full,
fifo_aempty => read_fifo_almost_empty,
data_w => read_fifo_din,
data_r => read_fifo_dout
);
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
u_cmd_we <= (not cmd_fifo_empty) and write_start and (not u_busy);
u_cmd <= cmd_fifo_out;
u_addr <= addr_fifo_out;
write_fifo_re <= u_req_wr and (not write_fifo_empty);
cmd_fifo_re <= u_cmd_we;
u_data_w <= write_fifo_dout;
read_fifo_re <= (not read_fifo_empty) and read_start;
read_fifo_we <= u_data_vld;
read_fifo_din <= u_data_r;
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait for 4*CLK_PERIOD;
wait until rising_edge(clk_out) and rst_out='0';
write_fifo_we <= '1';
cmd_fifo_we <= '1';
write_fifo_din <= X"01020304";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000000";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"05060708";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000002";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"00001111";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000004";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"22223333";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000006";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"44445555";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000008";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"66667777";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"00000a";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"88889999";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"00000c";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"AAAABBBB";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"00000e";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"CCCCDDDD";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000010";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"EEEEFFFF";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000012";
wait until rising_edge(clk_out);
write_fifo_we <= '0';
cmd_fifo_we <= '0';
-- wait until rising_edge(clk_out) and u_busy='0';
-- write_start <= '1';
-- wait until rising_edge(clk_out) and write_fifo_empty='1';
write_fifo_we <= '1';
cmd_fifo_we <= '1';
write_fifo_din <= X"01234567";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000014";
wait until rising_edge(clk_out);
write_fifo_we <= '0';
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"000014";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"89ABCDEF";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000016";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"11223344";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000018";
wait until rising_edge(clk_out);
write_fifo_we <= '0';
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"000010";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"55667788";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"00001a";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"99990000";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"00001c";
wait until rising_edge(clk_out);
write_fifo_we <= '1';
write_fifo_din <= X"AAAA5555";
cmd_fifo_in <= UCMD_WRITE;
addr_fifo_in <= X"000020";
wait until rising_edge(clk_out);
write_fifo_we <= '0';
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"000000";
wait until rising_edge(clk_out);
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"000018";
wait until rising_edge(clk_out);
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"00001A";
wait until rising_edge(clk_out);
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"00001C";
wait until rising_edge(clk_out);
cmd_fifo_in <= UCMD_READ;
addr_fifo_in <= X"000020";
wait until rising_edge(clk_out);
write_fifo_we <= '0';
cmd_fifo_we <= '0';
wait for 40*CLK_PERIOD;
read_start <= '1';
wait;
end process;
@@ -0,0 +1,318 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity tb_sdr_ctrl is
end;
architecture struct of tb_sdr_ctrl is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 8;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal lin_addr : user_addr_t := (others => '0');
signal rand_gen : unsigned(7 downto 0) := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal rw_null_en : std_logic := '0';
signal u_addr_cnt_en : std_logic := '0';
signal u_addr_load : std_logic := '0';
signal u_addr_preset : user_addr_t := (others => '0');
signal u_addr_end : user_addr_t := (others => '0');
signal ref_data : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
type test_phase_t is (IDLE, PART_INIT, WRITE_SINGLE, WRITE_MULTI, READ_SINGLE, READ_MULTI, FINISHED);
signal test_phase : test_phase_t := IDLE;
type u_addr_mode_t is (MONOTONIC, RANDOM);
signal u_addr_mode : u_addr_mode_t := MONOTONIC;
signal cycle_cnt : natural := 1;
signal data_cnt : natural := 0;
signal efficiency : real := 0.0;
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
R_DATA_COMPARE:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_data_vld='1' then
if u_read_en = '1' and u_tag_rd = "0000" then
assert (ref_data = u_data_r) report "Error on read!" severity failure;
for i in 0 to DDR_DATA_WIDTH/4-1 loop
ref_data((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
end if;
elsif u_read_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
ref_data <= (others => '0');
end if;
end if;
end process;
W_DATA_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_req_wr = '1' and u_tag_wr = "0000" then
for i in 0 to DDR_DATA_WIDTH/4-1 loop
u_data_w((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_write_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
u_data_w <= (others => '0');
end if;
end if;
end process;
ADDR_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_addr_load = '1' then
lin_addr <= u_addr_preset;
rand_gen <= X"80";
elsif u_addr_cnt_en = '1' then
lin_addr <= lin_addr + BURST_LEN;
if rand_gen(rand_gen'left) = '1' then
rand_gen <= (rand_gen(rand_gen'left-1 downto 0) & rand_gen(rand_gen'left)) xor "10010010";
else
rand_gen <= rand_gen(rand_gen'left-1 downto 0) & rand_gen(rand_gen'left);
end if;
end if;
end if;
end process;
performance_count:
process(clk_out)
begin
if rising_edge(clk_out) then
if u_write_en = '1' or u_read_en = '1' then
cycle_cnt <= cycle_cnt + 1;
if u_req_wr = '1' or u_req_rd = '1' then
data_cnt <= data_cnt + 1;
end if;
else
cycle_cnt <= 1;
data_cnt <= 0;
end if;
end if;
end process;
u_tag_in <= "000" & rw_null_en;
efficiency <= real(data_cnt)/real(cycle_cnt);
u_cmd_we <= (u_write_en or u_read_en or rw_null_en) and (not u_busy);
u_addr_cnt_en <= '1' when (u_cmd_we = '1' and (lin_addr /= u_addr_end)) else '0';
u_addr <= (rand_gen(7) and (not rw_null_en)) & lin_addr(lin_addr'left-1 downto 0);
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait until rising_edge(clk_out) and u_busy='0';
wait for 137*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= WRITE_MULTI;
u_addr_preset <= X"000000";
u_addr_end <= X"010000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_READ;
u_write_en <= '1';
rw_null_en <= '1';
while lin_addr /= u_addr_end loop
u_cmd <= UCMD_READ;
rw_null_en <= '1';
if rand_gen(3) = '0' and rand_gen(4) = '0' and rand_gen(5) = '0' and rand_gen(6) = '0' then
if rand_gen(1) = '1' or rand_gen(7) = '1' then
u_cmd <= UCMD_WRITE;
end if;
rw_null_en <= '0';
end if;
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
rw_null_en <= '0';
wait until rising_edge(clk_out) and u_req_wr='0';
wait for 200*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= READ_MULTI;
u_addr_preset <= X"000000";
u_addr_end <= X"010000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_WRITE;
u_read_en <= '1';
rw_null_en <= '1';
while lin_addr /= u_addr_end loop
u_cmd <= UCMD_WRITE;
rw_null_en <= '1';
if rand_gen(3) = '0' and rand_gen(4) = '0' and rand_gen(5) = '0' and rand_gen(6) = '0' then
if rand_gen(1) = '1' or rand_gen(7) = '1' then
u_cmd <= UCMD_READ;
end if;
rw_null_en <= '0';
end if;
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
rw_null_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait;
end process;
end architecture struct;
@@ -0,0 +1,316 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity tb_sdr_ctrl is
end;
architecture struct of tb_sdr_ctrl is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 8;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal lin_addr : user_addr_t := (others => '0');
signal rand_gen : unsigned(7 downto 0) := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal rw_null_en : std_logic := '0';
signal u_addr_cnt_en : std_logic := '0';
signal u_addr_load : std_logic := '0';
signal u_addr_preset : user_addr_t := (others => '0');
signal u_addr_end : user_addr_t := (others => '0');
signal ref_data : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
type test_phase_t is (IDLE, PART_INIT, WRITE_SINGLE, WRITE_MULTI, READ_SINGLE, READ_MULTI, FINISHED);
signal test_phase : test_phase_t := IDLE;
type u_addr_mode_t is (MONOTONIC, RANDOM);
signal u_addr_mode : u_addr_mode_t := MONOTONIC;
signal cycle_cnt : natural := 1;
signal data_cnt : natural := 0;
signal efficiency : real := 0.0;
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
R_DATA_COMPARE:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_data_vld='1' then
if u_read_en = '1' and u_tag_rd = "0000" then
assert (ref_data = u_data_r) report "Error on read!" severity failure;
for i in 0 to DDR_DATA_WIDTH/4-1 loop
ref_data((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
end if;
elsif u_read_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
ref_data <= (others => '0');
end if;
end if;
end process;
W_DATA_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_req_wr = '1' and u_tag_wr = "0000" then
for i in 0 to DDR_DATA_WIDTH/4-1 loop
u_data_w((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_write_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
u_data_w <= (others => '0');
end if;
end if;
end process;
ADDR_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_addr_load = '1' then
lin_addr <= u_addr_preset;
rand_gen <= X"80";
elsif u_addr_cnt_en = '1' then
lin_addr <= lin_addr + BURST_LEN;
if rand_gen(rand_gen'left) = '1' then
rand_gen <= (rand_gen(rand_gen'left-1 downto 0) & rand_gen(rand_gen'left)) xor "10010010";
else
rand_gen <= rand_gen(rand_gen'left-1 downto 0) & rand_gen(rand_gen'left);
end if;
end if;
end if;
end process;
performance_count:
process(clk_out)
begin
if rising_edge(clk_out) then
if u_write_en = '1' or u_read_en = '1' then
cycle_cnt <= cycle_cnt + 1;
if u_req_wr = '1' or u_req_rd = '1' then
data_cnt <= data_cnt + 1;
end if;
else
cycle_cnt <= 1;
data_cnt <= 0;
end if;
end if;
end process;
u_tag_in <= "000" & rw_null_en;
efficiency <= real(data_cnt)/real(cycle_cnt);
u_cmd_we <= (u_write_en or u_read_en or rw_null_en) and (not u_busy);
u_addr_cnt_en <= '1' when (u_cmd_we = '1' and (lin_addr /= u_addr_end)) else '0';
u_addr <= (rand_gen(7) and (rw_null_en)) & lin_addr(lin_addr'left-1 downto 0);
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait until rising_edge(clk_out) and u_busy='0';
wait for 137*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= WRITE_MULTI;
u_addr_preset <= X"000000";
u_addr_end <= X"010000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_WRITE;
u_write_en <= '1';
while lin_addr /= u_addr_end loop
u_cmd <= UCMD_WRITE;
rw_null_en <= '0';
if rand_gen(3) = '0' and rand_gen(4) = '0' and rand_gen(5) = '0' and rand_gen(6) = '0' then
if rand_gen(1) = '1' or rand_gen(7) = '1' then
u_cmd <= UCMD_READ;
end if;
rw_null_en <= '1';
end if;
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
rw_null_en <= '0';
wait until rising_edge(clk_out) and u_req_wr='0';
wait for 200*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= READ_MULTI;
u_addr_preset <= X"000000";
u_addr_end <= X"010000"-BURST_LEN;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_cmd <= UCMD_READ;
u_read_en <= '1';
while lin_addr /= u_addr_end loop
u_cmd <= UCMD_READ;
rw_null_en <= '0';
if rand_gen(3) = '0' and rand_gen(4) = '0' and rand_gen(5) = '0' and rand_gen(6) = '0' then
if rand_gen(1) = '1' or rand_gen(7) = '1' then
u_cmd <= UCMD_WRITE;
end if;
rw_null_en <= '1';
end if;
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
rw_null_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait;
end process;
end architecture struct;
@@ -0,0 +1,315 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity tb_sdr_ctrl is
end;
architecture struct of tb_sdr_ctrl is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 8;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal u_addr_cnt_en : std_logic := '0';
signal u_addr_load : std_logic := '0';
signal u_addr_preset : user_addr_t := (others => '0');
signal u_addr_end : user_addr_t := (others => '0');
signal ref_data : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
type test_phase_t is (IDLE, PART_INIT, WRITE_SINGLE, WRITE_MULTI, READ_SINGLE, READ_MULTI, FINISHED);
signal test_phase : test_phase_t := IDLE;
type u_addr_mode_t is (MONOTONIC, RANDOM);
signal u_addr_mode : u_addr_mode_t := MONOTONIC;
signal cycle_cnt : natural := 1;
signal data_cnt : natural := 0;
signal efficiency : real := 0.0;
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
R_DATA_COMPARE:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_data_vld='1' then
if u_read_en = '1' then
assert (ref_data = u_data_r) report "Error on read!" severity failure;
end if;
for i in 0 to DDR_DATA_WIDTH/4-1 loop
ref_data((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_read_en = '0' then
last_data := (others => '0');
ref_data <= (others => '0');
end if;
end if;
end process;
W_DATA_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_req_wr = '1' then
for i in 0 to DDR_DATA_WIDTH/4-1 loop
u_data_w((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_write_en = '0' then
last_data := (others => '0');
u_data_w <= (others => '0');
end if;
end if;
end process;
ADDR_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_addr_load = '1' then
u_addr <= u_addr_preset;
elsif u_addr_cnt_en = '1' then
if u_addr_mode = MONOTONIC then
u_addr <= u_addr + BURST_LEN;
else
if u_addr(u_addr'left) = '1' then
if BURST_LEN = 2 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "10000000000010001010100";
elsif BURST_LEN = 4 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "1000000000010011010110";
elsif BURST_LEN = 8 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "100000000001011110100";
end if;
else
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)-1) <= u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)-1) & u_addr(u_addr'left);
end if;
end if;
end if;
end if;
end process;
performance_count:
process(clk_out)
begin
if rising_edge(clk_out) then
if u_write_en = '1' or u_read_en = '1' then
cycle_cnt <= cycle_cnt + 1;
if u_req_wr = '1' or u_req_rd = '1' then
data_cnt <= data_cnt + 1;
end if;
else
cycle_cnt <= 1;
data_cnt <= 0;
end if;
end if;
end process;
u_tag_in <= ("00" & u_write_en & u_read_en) when ((u_addr = X"333C98" or u_addr = X"000100") and u_cmd_we = '1') else "0000";
efficiency <= real(data_cnt)/real(cycle_cnt);
u_cmd_we <= (u_write_en or u_read_en) and (not u_busy);
u_addr_cnt_en <= '1' when (u_cmd_we = '1' and (u_addr /= u_addr_end)) else '0';
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait until rising_edge(clk_out) and u_busy='0';
wait for 137*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= WRITE_MULTI;
u_addr_preset <= X"800000";
if BURST_LEN = 2 then
u_addr_end <= X"5E2330";
elsif BURST_LEN = 4 then
u_addr_end <= X"7DEDD0";
elsif BURST_LEN = 8 then
u_addr_end <= X"5666B0";
end if;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_addr_mode <= RANDOM;
u_cmd <= UCMD_WRITE;
u_write_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
wait until rising_edge(clk_out) and u_req_wr='0';
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= READ_MULTI;
u_addr_preset <= X"800000";
if BURST_LEN = 2 then
u_addr_end <= X"5E2330";
elsif BURST_LEN = 4 then
u_addr_end <= X"7DEDD0";
elsif BURST_LEN = 8 then
u_addr_end <= X"5666B0";
end if;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_addr_mode <= RANDOM;
u_cmd <= UCMD_READ;
u_read_en <= '1';
while u_addr /= u_addr_end loop
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait;
end process;
@@ -0,0 +1,329 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
use work.utils_pkg.all;
entity tb_sdr_ctrl is
end;
architecture struct of tb_sdr_ctrl is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 2;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_addr : user_addr_t := (others => '0');
signal u_tag_in : user_tag_t := "0000";
signal u_tag_rd : user_tag_t;
signal u_tag_wr : user_tag_t;
signal u_cmd : user_cmd_t := UCMD_NOP;
signal u_cmd_we : std_logic := '0';
signal u_busy : std_logic;
signal u_data_w : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_dm : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "0000";
signal u_data_r : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal u_data_vld : std_logic;
signal u_req_wr : std_logic;
signal u_req_rd : std_logic;
signal u_read_en : std_logic := '0';
signal u_write_en : std_logic := '0';
signal rw_null_en : std_logic := '0';
signal u_addr_cnt_en : std_logic := '0';
signal u_addr_load : std_logic := '0';
signal u_addr_preset : user_addr_t := (others => '0');
signal u_addr_end : user_addr_t := (others => '0');
signal ref_data : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
type test_phase_t is (IDLE, PART_INIT, WRITE_SINGLE, WRITE_MULTI, READ_SINGLE, READ_MULTI, FINISHED);
signal test_phase : test_phase_t := IDLE;
type u_addr_mode_t is (MONOTONIC, RANDOM);
signal u_addr_mode : u_addr_mode_t := MONOTONIC;
signal cycle_cnt : natural := 1;
signal data_cnt : natural := 0;
signal efficiency : real := 0.0;
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
-- User interface
u_data_vld => u_data_vld,
u_data_req_w => u_req_wr,
u_data_req_r => u_req_rd,
u_tag_in => u_tag_in,
u_tag_rd => u_tag_rd,
u_tag_wr => u_tag_wr,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
u_data_wr => u_data_w,
u_data_rd => u_data_r,
u_dm => u_dm,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
------------------------------------------------------------------------------------------
R_DATA_COMPARE:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_data_vld='1' then
if u_read_en = '1' then
assert (ref_data = u_data_r) report "Error on read!" severity failure;
end if;
for i in 0 to DDR_DATA_WIDTH/4-1 loop
ref_data((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_read_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
ref_data <= (others => '0');
end if;
end if;
end process;
W_DATA_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_req_wr = '1' then
for i in 0 to DDR_DATA_WIDTH/4-1 loop
u_data_w((i+1)*DDR_DATA_WIDTH/2-1 downto i*DDR_DATA_WIDTH/2) <= last_data + i + 1;
end loop;
last_data := last_data + DDR_DATA_WIDTH/4;
elsif u_write_en = '0' and rw_null_en = '0' then
last_data := (others => '0');
u_data_w <= (others => '0');
end if;
end if;
end process;
ADDR_GEN:
process(clk_out)
variable last_data : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(clk_out) then
if u_addr_load = '1' then
u_addr <= u_addr_preset;
elsif u_addr_cnt_en = '1' then
if u_addr_mode = MONOTONIC then
u_addr <= u_addr + BURST_LEN;
else
if u_addr(u_addr'left) = '1' then
if BURST_LEN = 2 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "10000000000010001010100";
elsif BURST_LEN = 4 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "1000000000010011010110";
elsif BURST_LEN = 8 then
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)) <= (u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)) & u_addr(u_addr'left)) xor "100000000001011110100";
end if;
else
u_addr(u_addr'left downto NextExpBaseTwo(BURST_LEN)-1) <= u_addr(u_addr'left-1 downto NextExpBaseTwo(BURST_LEN)-1) & u_addr(u_addr'left);
end if;
end if;
end if;
end if;
end process;
performance_count:
process(clk_out)
begin
if rising_edge(clk_out) then
if u_write_en = '1' or u_read_en = '1' then
cycle_cnt <= cycle_cnt + 1;
if u_req_wr = '1' or u_req_rd = '1' then
data_cnt <= data_cnt + 1;
end if;
else
cycle_cnt <= 1;
data_cnt <= 0;
end if;
end if;
end process;
u_tag_in <= ("00" & u_write_en & u_read_en) when ((u_addr = X"333C98" or u_addr = X"000100") and u_cmd_we = '1') else "0000";
efficiency <= real(data_cnt)/real(cycle_cnt);
u_cmd_we <= (u_write_en or u_read_en or rw_null_en) and (not u_busy);
u_addr_cnt_en <= '1' when (u_cmd_we = '1' and (u_addr /= u_addr_end)) else '0';
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait until rising_edge(clk_out) and u_busy='0';
wait for 137*CLK_PERIOD;
-- Bank 0
test_phase <= WRITE_MULTI;
u_addr_preset <= X"800000";
if BURST_LEN = 2 then
u_addr_end <= X"646808";
elsif BURST_LEN = 4 then
u_addr_end <= X"7DEDD0";
elsif BURST_LEN = 8 then
u_addr_end <= X"5666B0";
end if;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_addr_mode <= RANDOM;
while u_addr /= u_addr_end loop
u_cmd <= UCMD_WRITE;
u_write_en <= '1';
rw_null_en <= '0';
if u_addr(20) = '0' then
u_cmd <= UCMD_READ;
u_write_en <= '0';
rw_null_en <= '1';
end if;
wait until rising_edge(clk_out);
end loop;
u_write_en <= '0';
rw_null_en <= '0';
wait for 200*CLK_PERIOD;
wait until rising_edge(clk_out) and u_busy='0';
-- Bank 0
test_phase <= READ_MULTI;
u_addr_preset <= X"800000";
if BURST_LEN = 2 then
u_addr_end <= X"646808";
elsif BURST_LEN = 4 then
u_addr_end <= X"7DEDD0";
elsif BURST_LEN = 8 then
u_addr_end <= X"5666B0";
end if;
u_addr_load <= '1';
wait until rising_edge(clk_out);
u_addr_load <= '0';
wait until rising_edge(clk_out);
u_addr_mode <= RANDOM;
while u_addr /= u_addr_end loop
u_cmd <= UCMD_READ;
u_read_en <= '1';
rw_null_en <= '0';
if u_addr(20) = '0' then
u_cmd <= UCMD_WRITE;
u_read_en <= '0';
rw_null_en <= '1';
end if;
wait until rising_edge(clk_out);
end loop;
u_read_en <= '0';
rw_null_en <= '0';
wait until rising_edge(clk_out) and u_data_vld='0';
wait;
end process;
end architecture struct;
@@ -0,0 +1,385 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
entity tb_sdram_ctrl_frontend is
end;
architecture struct of tb_sdram_ctrl_frontend is
-- Number of user data words for simulation
constant CLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 2;
signal rst : std_logic := '1';
signal clk : std_logic := '0';
signal rst_out : std_logic;
signal clk_out : std_logic;
signal clk_fb : std_logic;
signal part_clk_p : std_logic;
signal part_clk_n : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(DDR_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dm : unsigned(DDR_DM_WIDTH-1 downto 0) := (others => '0');
signal part_dqs : unsigned(DDR_DQS_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(DDR_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal addr : user_addr_t := (others => '0');
signal r_wn : std_logic := '0';
signal en : std_logic := '0';
signal busy : std_logic;
signal din : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal be : unsigned(2*DDR_DM_WIDTH-1 downto 0) := "1111";
signal dout : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
signal dout_vld : std_logic;
signal dout_re : std_logic;
signal dout_reg : unsigned(2*DDR_DATA_WIDTH-1 downto 0) := (others => '0');
begin
clk_fb <= part_clk_p after 1 ns;
-- DDR SDRAM Controller Core
inst_sdram_ctrl_frontend : entity work.sdram_ctrl_frontend
Generic map
(
BL => BURST_LEN,
read_phaseshift => 0,
f_sysclk => 100E6,
fifo_depth => 4
)
Port map
(
sys_rst_in => rst,
sys_clk_in => clk,
sys_rst_out => rst_out,
sys_clk_out => clk_out,
sys_clk_fb => clk_fb,
busy => busy,
en => en,
r_wn => r_wn,
be => be,
addr => addr,
din => din,
dout => dout,
dout_re => dout_re,
dout_vld => dout_vld,
-- SDRAM signals
sd_clk_p => part_clk_p,
sd_clk_n => part_clk_n,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dm => part_dm,
sd_dqs => part_dqs,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
i_mt46v16m16_0 : entity work.mt46v16m16
port map (
dq => std_logic_vector(part_data),
dqs => std_logic_vector(part_dqs),
addr => std_logic_vector(part_addr),
ba => std_logic_vector(part_ba),
clk => part_clk_p,
clk_n => part_clk_n,
cke => part_cke,
cs_n => part_cs_n,
ras_n => part_ras_n,
cas_n => part_cas_n,
we_n => part_we_n,
dm => std_logic_vector(part_dm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
read_register:
process(clk_out)
begin
if rising_edge(clk_out) then
if dout_vld = '1' then
dout_reg <= dout;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
dout_re <= dout_vld;
process
begin
-- Write MAX_WORDS to DDR SDRAM Controller
wait for 4*CLK_PERIOD;
rst <= '0';
wait for 4*CLK_PERIOD;
wait until rising_edge(clk_out) and rst_out='0';
for i in 0 to 999 loop
en <= '1';
r_wn <= '0';
din <= to_unsigned(i, 32);
addr <= to_unsigned(2*i, 24);
wait until rising_edge(clk_out) and busy = '0';
end loop;
for i in 0 to 999 loop
en <= '1';
r_wn <= '1';
din <= to_unsigned(i, 32);
addr <= to_unsigned(2*i, 24);
wait until rising_edge(clk_out) and busy = '0';
end loop;
en <= '1';
r_wn <= '0';
din <= X"01020304";
addr <= X"000000";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"05060708";
addr <= X"000002";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"00001111";
addr <= X"000004";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"22223333";
addr <= X"000006";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"44445555";
addr <= X"000008";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"66667777";
addr <= X"00000a";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"88889999";
addr <= X"00000c";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"AAAABBBB";
addr <= X"00000e";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"CCCCDDDD";
addr <= X"000010";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"EEEEFFFF";
addr <= X"000012";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"FFFFFFFF";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"87CCCCCC";
be <= "1000";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"CC65CCCC";
be <= "0100";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"CCCC43CC";
be <= "0010";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"89ABCDEF";
addr <= X"000016";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"CCCCCC21";
be <= "0001";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"55555555";
be <= "1010";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"AAAAAAAA";
be <= "0101";
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '1';
addr <= X"000014";
wait until rising_edge(clk_out) and busy = '0';
be <= "1111";
en <= '1';
r_wn <= '0';
din <= X"11223344";
addr <= X"000018";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"000010";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"55667788";
addr <= X"00001a";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"99990000";
addr <= X"00001c";
wait until rising_edge(clk_out) and busy = '0';
en <= '1';
r_wn <= '0';
din <= X"AAAA5555";
addr <= X"000020";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"000000";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"000018";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"00001A";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"00001C";
wait until rising_edge(clk_out) and busy = '0';
r_wn <= '1';
addr <= X"000020";
wait until rising_edge(clk_out) and busy = '0';
en <= '0';
wait;
end process;