From 70e48af3ab9711b0bb2cbb1955754d0b986bfcbd Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 20 Jul 2014 13:30:14 +0000 Subject: [PATCH] - commit local changes after CVS2SVN git-svn-id: http://moon:8086/svn/vhdl/trunk@1036 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/doc/memory_map.vsd | Bin 36352 -> 35840 bytes lib/CPUs/MIPS/doc/mips_drawings.vsd | Bin 1437184 -> 1437184 bytes lib/CPUs/MIPS/syn/ise101/mips_top.prj | 43 +- lib/CPUs/MIPS/syn/ise101/mips_top_vhdl.prj | 43 +- lib/CPUs/MIPS/todo.txt | 75 +- lib/JBUS/sim/tb_busmaster_async.wdo | 133 +- lib/JBUS/src/busmaster_async.vhd | 554 +++---- lib/JBUS/src/busmaster_sync.vhd | 432 ++--- lib/JBUS/src/busmaster_types.vhd | 62 +- lib/JBUS/src/dmac.vhd | 459 +++--- lib/JBUS/src/tb_busmaster_async.vhd | 902 +++++------ lib/JBUS/src/tb_busmaster_sync.vhd | 892 +++++------ lib/JBUS/src/tb_dmac.vhd | 1080 ++++++------- lib/PCK_FIO-2002.7/CHANGES | 172 +- lib/PCK_FIO-2002.7/PCK_FIO.html | 678 ++++---- lib/PCK_FIO-2002.7/PCK_FIO_1987.vhd | 210 +-- lib/PCK_FIO-2002.7/PCK_FIO_1987_BODY.vhd | 1642 ++++++++++---------- lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd | 216 +-- lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd | 1628 +++++++++---------- lib/PCK_FIO-2002.7/README | 176 +-- lib/PCK_FIO-2002.7/TB_PCK_FIO_1987.vhd | 1062 ++++++------- lib/PCK_FIO-2002.7/TB_PCK_FIO_1993.vhd | 1072 ++++++------- lib/ac97_ctrl/sim/tb_ac97_wb.fdo | 4 +- lib/misc/async_port_wb.vhd | 634 ++++---- lib/misc/bbfifo.vhd | 246 +-- lib/misc/debounce.vhd | 182 +-- lib/misc/debounce2.vhd | 284 ++-- lib/misc/dpram_1w1r.vhd | 158 +- lib/misc/dpram_1w1r1c_sim.vhd | 154 +- lib/misc/dpram_1w1r1c_xil.vhd | 154 +- lib/misc/dpram_1w1r2c_sim.vhd | 164 +- lib/misc/dpram_1w1r2c_xil.vhd | 164 +- lib/misc/dpram_1w1r_dist.vhd | 168 +- lib/misc/dpram_1w2r1c_sim.vhd | 172 +- lib/misc/dpram_1w2r1c_xil.vhd | 160 +- lib/misc/dpram_2w2r.vhd | 176 +-- lib/misc/dpram_2w2r1c_sim.vhd | 176 +-- lib/misc/dpram_2w2r1c_xil.vhd | 164 +- lib/misc/dpram_2w2r2c_sim.vhd | 190 +-- lib/misc/dpram_2w2r2c_xil.vhd | 186 +-- lib/misc/flash_port_wb.vhd | 586 +++---- lib/misc/lcd_port.vhd | 138 +- lib/misc/oneshot.vhd | 446 +++--- lib/misc/pkg_template.vhd | 36 +- lib/misc/singleshot.vhd | 310 ++-- lib/misc/tb_template.vhd | 126 +- lib/misc/utils_pkg.vhd | 392 ++--- lib/radio/ddc/src/syn_ddc.vhd | 881 ++++++----- lib/rams/dpram_1w1r2c_ra_sim.vhd | 164 +- lib/rams/dpram_1w1r2c_ra_xil.vhd | 164 +- lib/rams/dpram_1w1r2c_ro_sim.vhd | 160 +- lib/rams/dpram_1w1r2c_ro_xil.vhd | 162 +- lib/rams/dpram_2w2r2c_ra_sim.vhd | 190 +-- lib/rams/dpram_2w2r2c_ra_xil.vhd | 186 +-- lib/rams/dpram_2w2r2c_ro_sim.vhd | 176 +-- lib/rams/dpram_2w2r2c_ro_xil.vhd | 176 +-- projects/mips_sys/sim/tb_mips_sys.fdo | 2 +- projects/mips_sys/src/tb_mips_sys.vhd | 8 +- 58 files changed, 9720 insertions(+), 9650 deletions(-) diff --git a/lib/CPUs/MIPS/doc/memory_map.vsd b/lib/CPUs/MIPS/doc/memory_map.vsd index 720cf6a53c2ae71578f5d7de9d9165d1bcd851b9..819cba2b65f556632f11b389689c267d2e19d9e5 100644 GIT binary patch delta 9939 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 XLED$rQ^>Ps;h36SQD30QK5h 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 K+QWyO@&6Clmu2h# diff --git a/lib/CPUs/MIPS/syn/ise101/mips_top.prj b/lib/CPUs/MIPS/syn/ise101/mips_top.prj index ea45b69..6925d0f 100644 --- a/lib/CPUs/MIPS/syn/ise101/mips_top.prj +++ b/lib/CPUs/MIPS/syn/ise101/mips_top.prj @@ -1,21 +1,22 @@ -vhdl work "../../../../FIFO/src/fifo_ctrl_pkg.vhd" -vhdl work "../../../../FIFO/src/gray_counter.vhd" -vhdl work "../../../../misc/dpram_2w2r.vhd" -vhdl work "../../../../misc/dpram_1w1r.vhd" -vhdl work "../../../../FIFO/src/fifo_sync_ctrl.vhd" -vhdl work "../../../../FIFO/src/fifo_async_ctrl.vhd" -vhdl work "../../src/core/mips_types.vhd" -vhdl work "../../../../FIFO/src/fifo_sync.vhd" -vhdl work "../../../../FIFO/src/fifo_async.vhd" -vhdl work "../../src/core/mips_shifter.vhd" -vhdl work "../../src/core/mips_reg.vhd" -vhdl work "../../src/core/mips_muldiv.vhd" -vhdl work "../../src/core/mips_instr.vhd" -vhdl work "../../src/core/mips_icache.vhd" -vhdl work "../../src/core/mips_dcache.vhd" -vhdl work "../../src/core/mips_bcu.vhd" -vhdl work "../../src/core/mips_alu.vhd" -vhdl work "../../src/core/mips_pipeline.vhd" -vhdl work "../../src/core/mips_cop.vhd" -vhdl work "../../src/core/mips_biu.vhd" -vhdl work "../../src/core/mips_top.vhd" +vhdl work "../../../../FIFO/src/fifo_ctrl_pkg.vhd" +vhdl work "../../../../FIFO/src/gray_counter.vhd" +vhdl work "../../../../rams/dpram_2w2r2c_ra_xil.vhd" +vhdl work "../../../../rams/dpram_1w1r2c_ro_xil.vhd" +vhdl work "../../../../rams/dpram_1w1r2c_ra_xil.vhd" +vhdl work "../../../../FIFO/src/fifo_sync_ctrl.vhd" +vhdl work "../../../../FIFO/src/fifo_async_ctrl.vhd" +vhdl work "../../src/core/mips_types.vhd" +vhdl work "../../../../FIFO/src/fifo_sync.vhd" +vhdl work "../../../../FIFO/src/fifo_async.vhd" +vhdl work "../../src/core/mips_shifter.vhd" +vhdl work "../../src/core/mips_reg.vhd" +vhdl work "../../src/core/mips_muldiv.vhd" +vhdl work "../../src/core/mips_instr.vhd" +vhdl work "../../src/core/mips_icache.vhd" +vhdl work "../../src/core/mips_dcache.vhd" +vhdl work "../../src/core/mips_bcu.vhd" +vhdl work "../../src/core/mips_alu.vhd" +vhdl work "../../src/core/mips_pipeline.vhd" +vhdl work "../../src/core/mips_cop.vhd" +vhdl work "../../src/core/mips_biu.vhd" +vhdl work "../../src/core/mips_top.vhd" diff --git a/lib/CPUs/MIPS/syn/ise101/mips_top_vhdl.prj b/lib/CPUs/MIPS/syn/ise101/mips_top_vhdl.prj index 7676319..3ccfc7d 100644 --- a/lib/CPUs/MIPS/syn/ise101/mips_top_vhdl.prj +++ b/lib/CPUs/MIPS/syn/ise101/mips_top_vhdl.prj @@ -1,21 +1,22 @@ -vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd" -vhdl work "W:\vhdl\lib\FIFO\src\gray_counter.vhd" -vhdl work "W:\vhdl\lib\misc\dpram_2w2r.vhd" -vhdl work "W:\vhdl\lib\misc\dpram_1w1r.vhd" -vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync_ctrl.vhd" -vhdl work "W:\vhdl\lib\FIFO\src\fifo_async_ctrl.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_types.vhd" -vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync.vhd" -vhdl work "W:\vhdl\lib\FIFO\src\fifo_async.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_shifter.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_reg.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_muldiv.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_instr.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_icache.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_dcache.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_bcu.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_alu.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_pipeline.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_cop.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_biu.vhd" -vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_top.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\gray_counter.vhd" +vhdl work "W:\vhdl\lib\rams\dpram_2w2r2c_ra_xil.vhd" +vhdl work "W:\vhdl\lib\rams\dpram_1w1r2c_ro_xil.vhd" +vhdl work "W:\vhdl\lib\rams\dpram_1w1r2c_ra_xil.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync_ctrl.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\fifo_async_ctrl.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_types.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync.vhd" +vhdl work "W:\vhdl\lib\FIFO\src\fifo_async.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_shifter.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_reg.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_muldiv.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_instr.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_icache.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_dcache.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_bcu.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_alu.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_pipeline.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_cop.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_biu.vhd" +vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_top.vhd" diff --git a/lib/CPUs/MIPS/todo.txt b/lib/CPUs/MIPS/todo.txt index 551e1a0..8f00f2a 100644 --- a/lib/CPUs/MIPS/todo.txt +++ b/lib/CPUs/MIPS/todo.txt @@ -1,35 +1,40 @@ -2008-10-26 -- Area-Optimierung: DIV und MUL verwenden gleiche Ressourcen -- Area-Optimierung: MUL32x32 primitive für Virtex-4 -- shifter: log shifter besser als built-in sll, srl, sra? Nein (2008-10-27) -- External COP 1..3 interface -- FPU (COP1) -- MMU - -2008-10-27 -- Area vs. speed : Pipeline-stall statt forwarding -- Caches: - Lock-up free cache (refill critical word first then un-lock CPU) (geringer Effekt, zu kompliziert => geringere Zuverlässigkeit) - - 1,2,4-way assoziative - - 2nd-Level cache in System - - Write-back policy - -2008-11-15 -- Bus exceptions IBE DBE (BUI/Cache restart notwendig) - -2009-03-18 -- cache line sizes von 1 word (4 bytes) gibt NULL-vector. Fehler in Berechnung der inedx_widths - -2009-8-8 -- Soft-Reset. Ähnlich wie Exception (Reset/NMI). Speicherung von EPC (done) -- CP_COND - -2009-10-17 -- Soft-reset implemetiert. Register werden wie bei normaler Exception verändert. - TodO: Bei Soft-reset (laut Buch) KUc=0, IEc=0 und BEV=1 initialisieren - -- Uncached write: Geht wie bei cached-write in den Write-Buffer. Folge: Mögliche lange Latenz bis uncached memory-mapped I/O tatsächlich geschieben wird. - Könnte bei IRQ acknowledging Probleme bereiten (z.b. mehrfaches (unötiges) anspringen der ISR, obwohl IRQ schon acknowleded wurde). - Work-around: Nach schreiben von memory-mapped I/O, gleiche Adresse zurücklesen (lesen wartet bis write-buffer leer). - -2010-01-09 -- COP dependency einführen => Pipeline stall, wenn COP Daten nicht verfügbar +2008-10-26 +- Area-Optimierung: DIV und MUL verwenden gleiche Ressourcen +- Area-Optimierung: MUL32x32 primitive für Virtex-4 +- shifter: log shifter besser als built-in sll, srl, sra? Nein (2008-10-27) +- External COP 1..3 interface +- FPU (COP1) +- MMU + +2008-10-27 +- Area vs. speed : Pipeline-stall statt forwarding +- Caches: - Lock-up free cache (refill critical word first then un-lock CPU) (geringer Effekt, zu kompliziert => geringere Zuverlässigkeit) + - 1,2,4-way assoziative + - 2nd-Level cache in System + - Write-back policy + +2008-11-15 +- Bus exceptions IBE DBE (BUI/Cache restart notwendig) + +2009-03-18 +- cache line sizes von 1 word (4 bytes) gibt NULL-vector. Fehler in Berechnung der inedx_widths + +2009-8-8 +- Soft-Reset. Ähnlich wie Exception (Reset/NMI). Speicherung von EPC (done) +- CP_COND + +2009-10-17 +- Soft-reset implemetiert. Register werden wie bei normaler Exception verändert. + TodO: Bei Soft-reset (laut Buch) KUc=0, IEc=0 und BEV=1 initialisieren + +- Uncached write: Geht wie bei cached-write in den Write-Buffer. Folge: Mögliche lange Latenz bis uncached memory-mapped I/O tatsächlich geschieben wird. + Könnte bei IRQ acknowledging Probleme bereiten (z.b. mehrfaches (unötiges) anspringen der ISR, obwohl IRQ schon acknowleded wurde). + Work-around: Nach schreiben von memory-mapped I/O, gleiche Adresse zurücklesen (lesen wartet bis write-buffer leer). + +2010-01-09 +- COP dependency einführen => Pipeline stall, wenn COP Daten nicht verfügbar + +213-08-25 +- TLB exception in EX-stage einbauen +- Cache dout und ready um logic-level reduzieren +- cam_ram_addr_rd um logic-level reduzieren diff --git a/lib/JBUS/sim/tb_busmaster_async.wdo b/lib/JBUS/sim/tb_busmaster_async.wdo index b45143d..4215417 100644 --- a/lib/JBUS/sim/tb_busmaster_async.wdo +++ b/lib/JBUS/sim/tb_busmaster_async.wdo @@ -1,59 +1,74 @@ -onerror {resume} -quietly WaveActivateNextPane {} 0 -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst -add wave -noupdate -divider J-BUS -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/ack_i -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/srdy_i -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/mdat_i -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/mdat_o -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/addr_o -add wave -noupdate -format Literal /tb_busmaster_async/inst_uut/sel_o -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/we_o -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cyc_o -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/stb_o -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/mrdy_o -add wave -noupdate -divider Busmaster -add wave -noupdate -format Logic /tb_busmaster_async/clk_o -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_cycle_finished -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_cycle_en -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_rdy -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_we -add wave -noupdate -format Literal -radix hexadecimal -expand /tb_busmaster_async/inst_uut/cmd_in -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/din -add wave -noupdate -format Logic /tb_busmaster_async/din_rdy -add wave -noupdate -format Logic /tb_busmaster_async/din_we -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/dout -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/dout_vld -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/dout_re -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cycle_busy -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_en -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_read_en -add wave -noupdate -format Literal /tb_busmaster_async/inst_uut/read_cnt -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cyc_o -add wave -noupdate -divider RAM -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk -add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst -add wave -noupdate -format Literal /tb_busmaster_async/state -add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/read_reg -add wave -noupdate -format Literal -radix hexadecimal -expand /tb_busmaster_async/ram64 -TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {31500000 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 1 -configure wave -griddelta 40 -configure wave -timeline 0 -update -WaveRestoreZoom {0 ps} {42 us} +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst +add wave -noupdate -divider J-BUS +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/ack_i +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/srdy_i +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/mdat_i +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/mdat_o +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/addr_o +add wave -noupdate -format Literal /tb_busmaster_async/inst_uut/sel_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/we_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cyc_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/stb_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/mrdy_o +add wave -noupdate -divider Busmaster +add wave -noupdate -format Logic /tb_busmaster_async/clk_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst +add wave -noupdate -format Literal /tb_busmaster_async/inst_uut/read_cnt +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/write +add wave -noupdate -format Literal -expand /tb_busmaster_async/inst_uut/debug +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_cycle_finished +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_cycle_en +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_rdy +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_we +add wave -noupdate -format Literal -radix hexadecimal -expand /tb_busmaster_async/inst_uut/cmd_in +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_fifo_empty +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_fifo_re +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/read_fifo_we +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/din +add wave -noupdate -format Logic /tb_busmaster_async/din_rdy +add wave -noupdate -format Logic /tb_busmaster_async/din_we +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/inst_uut/dout +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/dout_vld +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/dout_re +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cycle_busy +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cycle_active +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_en +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_read_en +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cyc_o +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_fifo_we +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/cmd_fifo_full +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/read_fifo_re +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/read_fifo_full +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/read_fifo_empty +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/write_fifo_re +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/write_fifo_we +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/write_fifo_full +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/write_fifo_empty +add wave -noupdate -divider RAM +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/clk +add wave -noupdate -format Logic /tb_busmaster_async/inst_uut/rst +add wave -noupdate -format Literal /tb_busmaster_async/state +add wave -noupdate -format Literal -radix hexadecimal /tb_busmaster_async/read_reg +add wave -noupdate -format Literal -radix hexadecimal -expand /tb_busmaster_async/ram64 +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {0 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 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {0 ps} {8639241 ps} diff --git a/lib/JBUS/src/busmaster_async.vhd b/lib/JBUS/src/busmaster_async.vhd index 3c5a90b..ccac16b 100644 --- a/lib/JBUS/src/busmaster_async.vhd +++ b/lib/JBUS/src/busmaster_async.vhd @@ -1,277 +1,277 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/busmaster_async.vhd,v 1.2 2013-08-04 17:58:37 jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.utils_pkg.all; -use work.busmaster_types.all; - ------------------------------------------------------------------- -entity busmaster_async is - Generic - ( - DATA_WIDTH : natural := 32; - FIFO_DEPTH : natural := 4 - ); - Port - ( - clk : in std_logic; - rst : in std_logic; - - cmd_cycle_finished : out std_logic; - cmd_cycle_en : in std_logic; - cmd_rdy : out std_logic; - cmd_we : in std_logic; - - cmd_in : in bm_cmd_t; - - din : in unsigned(DATA_WIDTH-1 downto 0); - din_rdy : out std_logic; - din_we : in std_logic; - - dout : out unsigned(DATA_WIDTH-1 downto 0); - dout_vld : out std_logic; - dout_re : in std_logic; - - -- J-BUS signals - RST_I : in STD_LOGIC; - CLK_I : in STD_LOGIC; - ACK_I : in std_logic; - SRDY_I : in std_logic; - MDAT_I : in unsigned(DATA_WIDTH-1 downto 0); - MDAT_O : out unsigned(DATA_WIDTH-1 downto 0); - ADDR_O : out unsigned(31 downto 0); - SEL_O : out unsigned(DATA_WIDTH/8-1 downto 0); - WE_O : out std_logic; - CYC_O : out std_logic; - STB_O : out std_logic; - MRDY_O : out std_logic - ); - end busmaster_async; - -architecture Behavioral of busmaster_async is - - -- Bus Command FIFO - signal cmd_fifo_din : unsigned(32+DATA_WIDTH/8+1-1 downto 0); - signal cmd_fifo_dout : unsigned(32+DATA_WIDTH/8+1-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; - - -- Bus Read FIFO - 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 write_fifo_re : std_logic; - signal write_fifo_we : std_logic; - signal write_fifo_full : std_logic; - signal write_fifo_empty : std_logic; - signal cycle_busy : std_logic; - signal cmd_en : std_logic; - signal cmd_read_en : std_logic; - signal read_cnt : integer range 0 to 65535; - signal write : std_logic; - - signal jbus_cycle_busy : std_logic; - - type jbus_state_t is (init, ready, start, wait_finish, finish1, finish2, finish3); - signal jbus_state : jbus_state_t; - signal jbus_state_next : jbus_state_t; - -begin - - cmd_en <= cmd_cycle_en and cmd_we and not cmd_fifo_full; - cmd_read_en <= cmd_en and not cmd_in.rw; - write <= cmd_fifo_dout(32+DATA_WIDTH/8); - - dout_vld <= not read_fifo_empty; - MRDY_O <= not read_fifo_full; - read_fifo_we <= ACK_I and jbus_cycle_busy; - read_fifo_re <= dout_re; - ADDR_O <= cmd_fifo_dout(31 downto 0); - SEL_O <= cmd_fifo_dout(32+DATA_WIDTH/8-1 downto 32); - WE_O <= write; - - cmd_fifo_din <= cmd_in.rw & cmd_in.sel & cmd_in.addr; - - cmd_rdy <= not cmd_fifo_full; - - cmd_fifo_we <= cmd_en; - cmd_fifo_re <= SRDY_I and jbus_cycle_busy; - - din_rdy <= not write_fifo_full; - write_fifo_we <= din_we; - write_fifo_re <= SRDY_I and jbus_cycle_busy and write and not cmd_fifo_empty; - - CYC_O <= jbus_cycle_busy; - STB_O <= not cmd_fifo_empty; - - --- J-Bus domain -proc_JBUS_to_local_cmd_cycle_finished: - process(clk) - begin - if rising_edge(clk) then - cmd_cycle_finished <= not jbus_cycle_busy; - end if; - end process; - -proc_JBUS_cycle: - process(CLK_I) - begin - if rising_edge(CLK_I) then - jbus_cycle_busy <= cycle_busy; - end if; - end process; - -proc_bus_read_counter: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - read_cnt <= 0; - elsif cmd_read_en = '1' and read_fifo_empty = '1' then - read_cnt <= read_cnt + 1; - elsif cmd_read_en = '0' and read_fifo_empty = '0' and dout_re = '1' then - read_cnt <= read_cnt - 1; - end if; - end if; - end process; - -jbus_state_fsm_next: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - jbus_state <= init; - else - jbus_state <= jbus_state_next; - end if; - end if; - end process; - -jbus_state_fsm: - process(jbus_state, cmd_we, cmd_fifo_empty, write_fifo_empty, read_cnt) - begin - - cycle_busy <= '0'; - jbus_state_next <= jbus_state; - - case jbus_state is - - when init => - jbus_state_next <= ready; - - when ready => - if cmd_we = '1' or cmd_fifo_empty = '0' then - jbus_state_next <= start; - end if; - - when start => - cycle_busy <= '1'; - if cmd_fifo_empty = '0' then - jbus_state_next <= wait_finish; - end if; - - when wait_finish => - cycle_busy <= '1'; - if read_cnt = 0 and cmd_fifo_empty = '1' and write_fifo_empty = '1' then - jbus_state_next <= finish1; - end if; - - -- Quick and dirty hack - -- avoid buscycle to finish even if data available, - -- caused by latency of async-FIFO empty flag - when finish1 => - jbus_state_next <= finish2; - - when finish2 => - jbus_state_next <= finish3; - - when finish3 => - jbus_state_next <= ready; - if cmd_fifo_empty = '0' then - jbus_state_next <= wait_finish; - end if; - -- Quick and dirty hack - - when others => - jbus_state_next <= ready; - - end case; - end process; - --- Bus READ FIFO -inst_BM_READ_FIFO: entity work.fifo_async - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => DATA_WIDTH, - do_last_read_update => true - ) - PORT MAP - ( - rst => rst, - clk_r => clk, - clk_w => CLK_I, - 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_r => dout, - data_w => MDAT_I - ); - --- Bus WRITE FIFO -inst_BM_WRITE_FIFO: entity work.fifo_async - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => DATA_WIDTH, - do_last_read_update => false - ) - PORT MAP - ( - rst => rst, - clk_r => CLK_I, - clk_w => clk, - 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_r => MDAT_O, - data_w => din - ); - --- Bus command FIFO -inst_BM_CMD_FIFO: entity work.fifo_async - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => cmd_fifo_din'length, - do_last_read_update => false - ) - PORT MAP - ( - rst => rst, - clk_r => CLK_I, - clk_w => clk, - 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_r => cmd_fifo_dout, - data_w => cmd_fifo_din - ); - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/busmaster_async.vhd,v 1.2 2013/08/04 17:58:37 jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +use work.utils_pkg.all; +use work.busmaster_types.all; + +------------------------------------------------------------------ +entity busmaster_async is + Generic + ( + DATA_WIDTH : natural := 32; + FIFO_DEPTH : natural := 4 + ); + Port + ( + clk : in std_logic; + rst : in std_logic; + + cmd_cycle_finished : out std_logic; + cmd_cycle_en : in std_logic; + cmd_rdy : out std_logic; + cmd_we : in std_logic; + + cmd_in : in bm_cmd_t; + + din : in unsigned(DATA_WIDTH-1 downto 0); + din_rdy : out std_logic; + din_we : in std_logic; + + dout : out unsigned(DATA_WIDTH-1 downto 0); + dout_vld : out std_logic; + dout_re : in std_logic; + + -- J-BUS signals + RST_I : in STD_LOGIC; + CLK_I : in STD_LOGIC; + ACK_I : in std_logic; + SRDY_I : in std_logic; + MDAT_I : in unsigned(DATA_WIDTH-1 downto 0); + MDAT_O : out unsigned(DATA_WIDTH-1 downto 0); + ADDR_O : out unsigned(31 downto 0); + SEL_O : out unsigned(DATA_WIDTH/8-1 downto 0); + WE_O : out std_logic; + CYC_O : out std_logic; + STB_O : out std_logic; + MRDY_O : out std_logic + ); + end busmaster_async; + +architecture Behavioral of busmaster_async is + + -- Bus Command FIFO + signal cmd_fifo_din : unsigned(32+DATA_WIDTH/8+1-1 downto 0); + signal cmd_fifo_dout : unsigned(32+DATA_WIDTH/8+1-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; + + -- Bus Read FIFO + 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 write_fifo_re : std_logic; + signal write_fifo_we : std_logic; + signal write_fifo_full : std_logic; + signal write_fifo_empty : std_logic; + signal cycle_busy : std_logic; + signal cmd_en : std_logic; + signal cmd_read_en : std_logic; + signal read_cnt : integer range 0 to 65535; + signal write : std_logic; + + signal jbus_cycle_busy : std_logic; + + type jbus_state_t is (init, ready, start, wait_finish, finish1, finish2, finish3); + signal jbus_state : jbus_state_t; + signal jbus_state_next : jbus_state_t; + +begin + + cmd_en <= cmd_cycle_en and cmd_we and not cmd_fifo_full; + cmd_read_en <= cmd_en and not cmd_in.rw; + write <= cmd_fifo_dout(32+DATA_WIDTH/8); + + dout_vld <= not read_fifo_empty; + MRDY_O <= not read_fifo_full; + read_fifo_we <= ACK_I and jbus_cycle_busy; + read_fifo_re <= dout_re; + ADDR_O <= cmd_fifo_dout(31 downto 0); + SEL_O <= cmd_fifo_dout(32+DATA_WIDTH/8-1 downto 32); + WE_O <= write; + + cmd_fifo_din <= cmd_in.rw & cmd_in.sel & cmd_in.addr; + + cmd_rdy <= not cmd_fifo_full; + + cmd_fifo_we <= cmd_en; + cmd_fifo_re <= SRDY_I and jbus_cycle_busy; + + din_rdy <= not write_fifo_full; + write_fifo_we <= din_we; + write_fifo_re <= SRDY_I and jbus_cycle_busy and write and not cmd_fifo_empty; + + CYC_O <= jbus_cycle_busy; + STB_O <= not cmd_fifo_empty; + + +-- J-Bus domain +proc_JBUS_to_local_cmd_cycle_finished: + process(clk) + begin + if rising_edge(clk) then + cmd_cycle_finished <= not jbus_cycle_busy; + end if; + end process; + +proc_JBUS_cycle: + process(CLK_I) + begin + if rising_edge(CLK_I) then + jbus_cycle_busy <= cycle_busy; + end if; + end process; + +proc_bus_read_counter: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + read_cnt <= 0; + elsif cmd_read_en = '1' and read_fifo_empty = '1' then + read_cnt <= read_cnt + 1; + elsif cmd_read_en = '0' and read_fifo_empty = '0' and dout_re = '1' then + read_cnt <= read_cnt - 1; + end if; + end if; + end process; + +jbus_state_fsm_next: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + jbus_state <= init; + else + jbus_state <= jbus_state_next; + end if; + end if; + end process; + +jbus_state_fsm: + process(jbus_state, cmd_we, cmd_fifo_empty, write_fifo_empty, read_cnt) + begin + + cycle_busy <= '0'; + jbus_state_next <= jbus_state; + + case jbus_state is + + when init => + jbus_state_next <= ready; + + when ready => + if cmd_we = '1' or cmd_fifo_empty = '0' then + jbus_state_next <= start; + end if; + + when start => + cycle_busy <= '1'; + if cmd_fifo_empty = '0' then + jbus_state_next <= wait_finish; + end if; + + when wait_finish => + cycle_busy <= '1'; + if read_cnt = 0 and cmd_fifo_empty = '1' and write_fifo_empty = '1' then + jbus_state_next <= finish1; + end if; + + -- Quick and dirty hack + -- avoid buscycle to finish even if data available, + -- caused by latency of async-FIFO empty flag + when finish1 => + jbus_state_next <= finish2; + + when finish2 => + jbus_state_next <= finish3; + + when finish3 => + jbus_state_next <= ready; + if cmd_fifo_empty = '0' then + jbus_state_next <= wait_finish; + end if; + -- Quick and dirty hack + + when others => + jbus_state_next <= ready; + + end case; + end process; + +-- Bus READ FIFO +inst_BM_READ_FIFO: entity work.fifo_async + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => DATA_WIDTH, + do_last_read_update => true + ) + PORT MAP + ( + rst => rst, + clk_r => clk, + clk_w => CLK_I, + 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_r => dout, + data_w => MDAT_I + ); + +-- Bus WRITE FIFO +inst_BM_WRITE_FIFO: entity work.fifo_async + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => DATA_WIDTH, + do_last_read_update => false + ) + PORT MAP + ( + rst => rst, + clk_r => CLK_I, + clk_w => clk, + 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_r => MDAT_O, + data_w => din + ); + +-- Bus command FIFO +inst_BM_CMD_FIFO: entity work.fifo_async + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => cmd_fifo_din'length, + do_last_read_update => false + ) + PORT MAP + ( + rst => rst, + clk_r => CLK_I, + clk_w => clk, + 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_r => cmd_fifo_dout, + data_w => cmd_fifo_din + ); + +end Behavioral; diff --git a/lib/JBUS/src/busmaster_sync.vhd b/lib/JBUS/src/busmaster_sync.vhd index 406e1d3..5a91df1 100644 --- a/lib/JBUS/src/busmaster_sync.vhd +++ b/lib/JBUS/src/busmaster_sync.vhd @@ -1,216 +1,216 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/busmaster_sync.vhd,v 1.6 2013-08-03 19:31:19 jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.utils_pkg.all; -use work.busmaster_types.all; - ------------------------------------------------------------------- -entity busmaster_sync is - Generic - ( - DATA_WIDTH : natural := 32; - FIFO_DEPTH : natural := 4 - ); - Port - ( - clk : in std_logic; - rst : in std_logic; - - cmd_cycle_finished : out std_logic; - cmd_cycle_en : in std_logic; - cmd_rdy : out std_logic; - cmd_we : in std_logic; - - cmd_in : in bm_cmd_t; - - din : in unsigned(DATA_WIDTH-1 downto 0); - din_rdy : out std_logic; - din_we : in std_logic; - - dout : out unsigned(DATA_WIDTH-1 downto 0); - dout_vld : out std_logic; - dout_re : in std_logic; - - -- J-BUS signals - ACK_I : in std_logic; - SRDY_I : in std_logic; - MDAT_I : in unsigned(DATA_WIDTH-1 downto 0); - MDAT_O : out unsigned(DATA_WIDTH-1 downto 0); - ADDR_O : out unsigned(31 downto 0); - SEL_O : out unsigned(DATA_WIDTH/8-1 downto 0); - WE_O : out std_logic; - CYC_O : out std_logic; - STB_O : out std_logic; - MRDY_O : out std_logic - ); - end busmaster_sync; - -architecture Behavioral of busmaster_sync is - - -- Bus Command FIFO - signal cmd_fifo_din : unsigned(32+DATA_WIDTH/8+1-1 downto 0); - signal cmd_fifo_dout : unsigned(32+DATA_WIDTH/8+1-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; - - -- Bus Read FIFO - 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 write_fifo_re : std_logic; - signal write_fifo_we : std_logic; - signal write_fifo_full : std_logic; - signal write_fifo_empty : std_logic; - signal cycle_busy : std_logic; - signal cmd_en : std_logic; - signal cmd_read_en : std_logic; - signal read_cnt : integer range 0 to 65535; - signal write : std_logic; - -begin - - cmd_en <= cmd_cycle_en and cmd_we and not cmd_fifo_full; - cmd_read_en <= cmd_en and not cmd_in.rw; - write <= cmd_fifo_dout(32+DATA_WIDTH/8); - - dout_vld <= not read_fifo_empty; - MRDY_O <= not read_fifo_full; - read_fifo_we <= ACK_I and cycle_busy; - read_fifo_re <= dout_re; - ADDR_O <= cmd_fifo_dout(31 downto 0); - SEL_O <= cmd_fifo_dout(32+DATA_WIDTH/8-1 downto 32); - WE_O <= write; - - cmd_fifo_din <= cmd_in.rw & cmd_in.sel & cmd_in.addr; - - cmd_rdy <= not cmd_fifo_full; - - cmd_fifo_we <= cmd_en; - cmd_fifo_re <= SRDY_I and cycle_busy; - - din_rdy <= not write_fifo_full; - write_fifo_we <= din_we; - write_fifo_re <= SRDY_I and cycle_busy and write and not cmd_fifo_empty; - - STB_O <= not cmd_fifo_empty; - CYC_O <= cycle_busy; - cmd_cycle_finished <= not cycle_busy; - --- proc_bus_read_counter: --- process(clk) --- begin --- if rising_edge(clk) then --- if rst = '1' then --- read_cnt <= 0; --- elsif cmd_read_en = '1' and read_fifo_we = '0' then --- read_cnt <= read_cnt + 1; --- elsif cmd_read_en = '0' and read_fifo_we = '1' then --- read_cnt <= read_cnt - 1; --- end if; --- end if; --- end process; - -proc_bus_read_counter: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - read_cnt <= 0; - elsif cmd_read_en = '1' and read_fifo_empty = '1' then - read_cnt <= read_cnt + 1; - elsif cmd_read_en = '0' and read_fifo_empty = '0' and dout_re = '1' then - read_cnt <= read_cnt - 1; - end if; - end if; - end process; - -proc_cycle_busy: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - cycle_busy <= '0'; - elsif cmd_cycle_en = '1' then - if cmd_we = '1' then - cycle_busy <= '1'; - end if; - elsif read_cnt = 0 and cmd_fifo_empty = '1' and write_fifo_empty = '1' then - cycle_busy <= '0'; - end if; - end if; - end process; - --- Bus READ FIFO -inst_BM_READ_FIFO: entity work.fifo_sync - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => DATA_WIDTH, - do_last_read_update => true - ) - PORT MAP - ( - rst => rst, - clk => clk, - 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 => MDAT_I, - data_r => dout - ); - --- Bus WRITE FIFO -inst_BM_WRITE_FIFO: entity work.fifo_sync - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => DATA_WIDTH, - do_last_read_update => false - ) - PORT MAP - ( - rst => rst, - clk => clk, - 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 => din, - data_r => MDAT_O - ); - --- Bus command FIFO -inst_BM_CMD_FIFO: entity work.fifo_sync - GENERIC MAP - ( - addr_width => NextExpBaseTwo(FIFO_DEPTH), - data_width => cmd_fifo_din'length, - do_last_read_update => false - ) - PORT MAP - ( - rst => rst, - clk => clk, - 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 - ); - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/busmaster_sync.vhd,v 1.6 2013/08/03 19:31:19 jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +use work.utils_pkg.all; +use work.busmaster_types.all; + +------------------------------------------------------------------ +entity busmaster_sync is + Generic + ( + DATA_WIDTH : natural := 32; + FIFO_DEPTH : natural := 4 + ); + Port + ( + clk : in std_logic; + rst : in std_logic; + + cmd_cycle_finished : out std_logic; + cmd_cycle_en : in std_logic; + cmd_rdy : out std_logic; + cmd_we : in std_logic; + + cmd_in : in bm_cmd_t; + + din : in unsigned(DATA_WIDTH-1 downto 0); + din_rdy : out std_logic; + din_we : in std_logic; + + dout : out unsigned(DATA_WIDTH-1 downto 0); + dout_vld : out std_logic; + dout_re : in std_logic; + + -- J-BUS signals + ACK_I : in std_logic; + SRDY_I : in std_logic; + MDAT_I : in unsigned(DATA_WIDTH-1 downto 0); + MDAT_O : out unsigned(DATA_WIDTH-1 downto 0); + ADDR_O : out unsigned(31 downto 0); + SEL_O : out unsigned(DATA_WIDTH/8-1 downto 0); + WE_O : out std_logic; + CYC_O : out std_logic; + STB_O : out std_logic; + MRDY_O : out std_logic + ); + end busmaster_sync; + +architecture Behavioral of busmaster_sync is + + -- Bus Command FIFO + signal cmd_fifo_din : unsigned(32+DATA_WIDTH/8+1-1 downto 0); + signal cmd_fifo_dout : unsigned(32+DATA_WIDTH/8+1-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; + + -- Bus Read FIFO + 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 write_fifo_re : std_logic; + signal write_fifo_we : std_logic; + signal write_fifo_full : std_logic; + signal write_fifo_empty : std_logic; + signal cycle_busy : std_logic; + signal cmd_en : std_logic; + signal cmd_read_en : std_logic; + signal read_cnt : integer range 0 to 65535; + signal write : std_logic; + +begin + + cmd_en <= cmd_cycle_en and cmd_we and not cmd_fifo_full; + cmd_read_en <= cmd_en and not cmd_in.rw; + write <= cmd_fifo_dout(32+DATA_WIDTH/8); + + dout_vld <= not read_fifo_empty; + MRDY_O <= not read_fifo_full; + read_fifo_we <= ACK_I and cycle_busy; + read_fifo_re <= dout_re; + ADDR_O <= cmd_fifo_dout(31 downto 0); + SEL_O <= cmd_fifo_dout(32+DATA_WIDTH/8-1 downto 32); + WE_O <= write; + + cmd_fifo_din <= cmd_in.rw & cmd_in.sel & cmd_in.addr; + + cmd_rdy <= not cmd_fifo_full; + + cmd_fifo_we <= cmd_en; + cmd_fifo_re <= SRDY_I and cycle_busy; + + din_rdy <= not write_fifo_full; + write_fifo_we <= din_we; + write_fifo_re <= SRDY_I and cycle_busy and write and not cmd_fifo_empty; + + STB_O <= not cmd_fifo_empty; + CYC_O <= cycle_busy; + cmd_cycle_finished <= not cycle_busy; + +-- proc_bus_read_counter: +-- process(clk) +-- begin +-- if rising_edge(clk) then +-- if rst = '1' then +-- read_cnt <= 0; +-- elsif cmd_read_en = '1' and read_fifo_we = '0' then +-- read_cnt <= read_cnt + 1; +-- elsif cmd_read_en = '0' and read_fifo_we = '1' then +-- read_cnt <= read_cnt - 1; +-- end if; +-- end if; +-- end process; + +proc_bus_read_counter: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + read_cnt <= 0; + elsif cmd_read_en = '1' and read_fifo_empty = '1' then + read_cnt <= read_cnt + 1; + elsif cmd_read_en = '0' and read_fifo_empty = '0' and dout_re = '1' then + read_cnt <= read_cnt - 1; + end if; + end if; + end process; + +proc_cycle_busy: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + cycle_busy <= '0'; + elsif cmd_cycle_en = '1' then + if cmd_we = '1' then + cycle_busy <= '1'; + end if; + elsif read_cnt = 0 and cmd_fifo_empty = '1' and write_fifo_empty = '1' then + cycle_busy <= '0'; + end if; + end if; + end process; + +-- Bus READ FIFO +inst_BM_READ_FIFO: entity work.fifo_sync + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => DATA_WIDTH, + do_last_read_update => true + ) + PORT MAP + ( + rst => rst, + clk => clk, + 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 => MDAT_I, + data_r => dout + ); + +-- Bus WRITE FIFO +inst_BM_WRITE_FIFO: entity work.fifo_sync + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => DATA_WIDTH, + do_last_read_update => false + ) + PORT MAP + ( + rst => rst, + clk => clk, + 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 => din, + data_r => MDAT_O + ); + +-- Bus command FIFO +inst_BM_CMD_FIFO: entity work.fifo_sync + GENERIC MAP + ( + addr_width => NextExpBaseTwo(FIFO_DEPTH), + data_width => cmd_fifo_din'length, + do_last_read_update => false + ) + PORT MAP + ( + rst => rst, + clk => clk, + 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 + ); + +end Behavioral; diff --git a/lib/JBUS/src/busmaster_types.vhd b/lib/JBUS/src/busmaster_types.vhd index db77b3d..5d3c2b6 100644 --- a/lib/JBUS/src/busmaster_types.vhd +++ b/lib/JBUS/src/busmaster_types.vhd @@ -1,31 +1,31 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/busmaster_types.vhd,v 1.2 2013-05-27 11:17:51 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use IEEE.MATH_REAL.ALL; - -package busmaster_types is - - -- Constants - - -- Types - - type bm_cmd_t is - record - addr : unsigned(31 downto 0); - sel : unsigned(3 downto 0); - rw : std_logic; - end record; - -end busmaster_types; - - -package body busmaster_types is - - -end busmaster_types; - - +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/busmaster_types.vhd,v 1.2 2013/05/27 11:17:51 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use IEEE.MATH_REAL.ALL; + +package busmaster_types is + + -- Constants + + -- Types + + type bm_cmd_t is + record + addr : unsigned(31 downto 0); + sel : unsigned(3 downto 0); + rw : std_logic; + end record; + +end busmaster_types; + + +package body busmaster_types is + + +end busmaster_types; + + diff --git a/lib/JBUS/src/dmac.vhd b/lib/JBUS/src/dmac.vhd index 0674a36..d1e7dc5 100644 --- a/lib/JBUS/src/dmac.vhd +++ b/lib/JBUS/src/dmac.vhd @@ -1,229 +1,230 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/dmac.vhd,v 1.2 2013-05-28 11:23:15 jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -use work.utils_pkg.all; -use work.busmaster_types.all; - ------------------------------------------------------------------- -entity dmac is - Generic - ( - DATA_WIDTH : natural := 32; - XFER_CHUNK_SIZE : natural := 512 - ); - Port - ( - clk : in std_logic; - rst : in std_logic; - - master_req : out std_logic; - master_gnt : in std_logic; - - dma_start : out std_logic; - dma_active : out std_logic; - dma_end : out std_logic; - - req_rdy : out std_logic; - req_en : in std_logic; - req_rw : in std_logic; - req_addr_start : in unsigned(31 downto 0); - req_num_xfers : in unsigned(31 downto 0); - req_addr_auto_inc : in std_logic; - - req_complete : out std_logic; - req_complete_ack : in std_logic; - - -- busmaster control - bus_cyc_complete : in std_logic; - bus_cmd_rdy : in std_logic; - bus_cmd_we : out std_logic; - bus_cmd_cycle_en : out std_logic; - - -- busmaster command - bus_cmd_out : out bm_cmd_t - ); - end dmac; - -architecture Behavioral of dmac is - - signal start_en : std_logic; - signal finish_en : std_logic; - signal complete : std_logic; - signal addr_inc_en : std_logic; - signal addr : unsigned(31 downto 0); - signal rw : std_logic; - - signal req_count_en : std_logic; - signal req_count : unsigned(31 downto 0); - signal req_count_next : unsigned(32 downto 0); - signal req_count_rdy : std_logic; - - signal chunk_count_rst : std_logic; - signal chunk_count_en : std_logic; - signal chunk_count : unsigned(31 downto 0); - signal chunk_count_next : unsigned(32 downto 0); - signal chunk_count_rdy : std_logic; - - type state_t is (INIT, READY, START, SETUP, XFER, FINISH, DONE); - signal s, sn : state_t; - -begin - - bus_cmd_out.addr <= addr; - bus_cmd_out.sel <= (others => '1'); - bus_cmd_out.rw <= rw; - req_complete <= complete; - -state_next: - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - s <= INIT; - else - s <= sn; - end if; - end if; - end process; - -state: - process(s, req_en, master_gnt, req_count_rdy, chunk_count_rdy, bus_cyc_complete, bus_cmd_rdy) - begin - - bus_cmd_cycle_en <= '0'; - bus_cmd_we <= '0'; - start_en <= '0'; - finish_en <= '0'; - req_count_en <= '0'; - req_rdy <= '0'; - chunk_count_rst <= '0'; - chunk_count_en <= '0'; - master_req <= '0'; - dma_start <= '0'; - dma_active <= '0'; - dma_end <= '0'; - - sn <= s; - case s is - when INIT => - sn <= READY; - - when READY => - req_rdy <= '1'; - if req_en = '1' then - start_en <= '1'; - sn <= SETUP; - end if; - - when SETUP => - dma_start <= '1'; - sn <= START; - - when START => - master_req <= '1'; - chunk_count_rst <= '1'; - if req_count_rdy = '1' then - sn <= READY; - elsif master_gnt = '1' and bus_cyc_complete = '1' then - sn <= XFER; - end if; - - when XFER => - dma_active <= '1'; - master_req <= '1'; - bus_cmd_we <= '1'; - bus_cmd_cycle_en <= '1'; - req_count_en <= bus_cmd_rdy; - chunk_count_en <= bus_cmd_rdy; - if req_count_rdy = '1' then - sn <= FINISH; - elsif chunk_count_rdy = '1' then - sn <= START; - end if; - - when FINISH => - master_req <= '1'; - if bus_cyc_complete = '1' then - sn <= DONE; - finish_en <= '1'; - end if; - - when DONE => - dma_end <= '1'; - sn <= READY; - - when others => - sn <= READY; - - end case; - end process; - -addr_gen: - process(clk) - begin - if rising_edge(clk) then - if start_en = '1' then - rw <= req_rw; - addr <= req_addr_start; - addr_inc_en <= req_addr_auto_inc; - elsif req_count_en = '1' and addr_inc_en = '1' then - addr <= addr + DATA_WIDTH/8; - end if; - end if; - end process; - - req_count_next <= ('0' & req_num_xfers) - 1 when start_en = '1' else ('0' & req_count) - 1; - req_count_rdy <= req_count_next(32); - -req_counter: - process(clk) - begin - if rising_edge(clk) then - if start_en = '1' then - req_count <= req_count_next(31 downto 0); - elsif req_count_en = '1' then - if req_count_rdy = '0' then - req_count <= req_count_next(31 downto 0); - end if; - end if; - end if; - end process; - - chunk_count_next <= to_unsigned(XFER_CHUNK_SIZE, 33) - 1 when chunk_count_rst = '1' else ('0' & chunk_count) - 1; - chunk_count_rdy <= chunk_count_next(32); - -chunk_counter: - process(clk) - begin - if rising_edge(clk) then - if chunk_count_rst = '1' then - chunk_count <= chunk_count_next(31 downto 0); - elsif chunk_count_en = '1' then - if chunk_count_rdy = '0' then - chunk_count <= chunk_count_next(31 downto 0); - end if; - end if; - end if; - end process; - -complete_register: - process(clk) - begin - if rising_edge(clk) then - if start_en = '1' or rst = '1' then - complete <= '0'; - elsif complete = '0' then - if finish_en = '1' then - complete <= '1'; - elsif req_complete_ack = '1' then - complete <= '0'; - end if; - end if; - end if; - end process; - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/dmac.vhd,v 1.2 2013/05/28 11:23:15 jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +use work.utils_pkg.all; +use work.busmaster_types.all; + +------------------------------------------------------------------ +entity dmac is + Generic + ( + DATA_WIDTH : natural := 32; + XFER_CHUNK_SIZE : natural := 512 + ); + Port + ( + clk : in std_logic; + rst : in std_logic; + + master_req : out std_logic; + master_gnt : in std_logic; + + dma_start : out std_logic; + dma_active : out std_logic; + dma_end : out std_logic; + + req_rdy : out std_logic; + req_en : in std_logic; + req_rw : in std_logic; + req_addr_start : in unsigned(31 downto 0); + req_num_xfers : in unsigned(31 downto 0); + req_addr_auto_inc : in std_logic; + + req_complete : out std_logic; + req_complete_ack : in std_logic; + + -- busmaster control + bus_cyc_complete : in std_logic; + bus_cmd_rdy : in std_logic; + bus_cmd_we : out std_logic; + bus_cmd_cycle_en : out std_logic; + + -- busmaster command + bus_cmd_out : out bm_cmd_t + ); + end dmac; + +architecture Behavioral of dmac is + + signal start_en : std_logic; + signal finish_en : std_logic; + signal complete : std_logic; + signal addr_inc_en : std_logic; + signal addr : unsigned(31 downto 0); + signal rw : std_logic; + + signal req_count_en : std_logic; + signal req_count : unsigned(31 downto 0); + signal req_count_next : unsigned(32 downto 0); + signal req_count_rdy : std_logic; + + signal chunk_count_rst : std_logic; + signal chunk_count_en : std_logic; + signal chunk_count : unsigned(31 downto 0); + signal chunk_count_next : unsigned(32 downto 0); + signal chunk_count_rdy : std_logic; + + type state_t is (INIT, READY, START, SETUP, XFER, FINISH, DONE); + signal s, sn : state_t; + +begin + + bus_cmd_out.addr <= addr; + bus_cmd_out.sel <= (others => '1'); + bus_cmd_out.rw <= rw; + req_complete <= complete; + +state_next: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + s <= INIT; + else + s <= sn; + end if; + end if; + end process; + +state: + process(s, req_en, master_gnt, req_count_rdy, chunk_count_rdy, bus_cyc_complete, bus_cmd_rdy) + begin + + bus_cmd_cycle_en <= '0'; + bus_cmd_we <= '0'; + start_en <= '0'; + finish_en <= '0'; + req_count_en <= '0'; + req_rdy <= '0'; + chunk_count_rst <= '0'; + chunk_count_en <= '0'; + master_req <= '0'; + dma_start <= '0'; + dma_active <= '0'; + dma_end <= '0'; + + sn <= s; + case s is + when INIT => + sn <= READY; + + when READY => + req_rdy <= '1'; + if req_en = '1' then + start_en <= '1'; + sn <= SETUP; + end if; + + when SETUP => + dma_start <= '1'; + sn <= START; + + when START => + master_req <= '1'; + chunk_count_rst <= '1'; + if req_count_rdy = '1' then + sn <= READY; + elsif master_gnt = '1' and bus_cyc_complete = '1' then + sn <= XFER; + end if; + + when XFER => + dma_active <= '1'; + master_req <= '1'; + bus_cmd_we <= '1'; + bus_cmd_cycle_en <= '1'; + req_count_en <= bus_cmd_rdy; + chunk_count_en <= bus_cmd_rdy; + if req_count_rdy = '1' then + sn <= FINISH; + elsif chunk_count_rdy = '1' then + sn <= START; + end if; + + when FINISH => + master_req <= '1'; + dma_end <= '1'; + sn <= DONE; + + when DONE => + master_req <= '1'; + if bus_cyc_complete = '1' then + sn <= READY; + finish_en <= '1'; + end if; + + when others => + sn <= READY; + + end case; + end process; + +addr_gen: + process(clk) + begin + if rising_edge(clk) then + if start_en = '1' then + rw <= req_rw; + addr <= req_addr_start; + addr_inc_en <= req_addr_auto_inc; + elsif req_count_en = '1' and addr_inc_en = '1' then + addr <= addr + DATA_WIDTH/8; + end if; + end if; + end process; + + req_count_next <= ('0' & req_num_xfers) - 1 when start_en = '1' else ('0' & req_count) - 1; + req_count_rdy <= req_count_next(32); + +req_counter: + process(clk) + begin + if rising_edge(clk) then + if start_en = '1' then + req_count <= req_count_next(31 downto 0); + elsif req_count_en = '1' then + if req_count_rdy = '0' then + req_count <= req_count_next(31 downto 0); + end if; + end if; + end if; + end process; + + chunk_count_next <= to_unsigned(XFER_CHUNK_SIZE, 33) - 1 when chunk_count_rst = '1' else ('0' & chunk_count) - 1; + chunk_count_rdy <= chunk_count_next(32); + +chunk_counter: + process(clk) + begin + if rising_edge(clk) then + if chunk_count_rst = '1' then + chunk_count <= chunk_count_next(31 downto 0); + elsif chunk_count_en = '1' then + if chunk_count_rdy = '0' then + chunk_count <= chunk_count_next(31 downto 0); + end if; + end if; + end if; + end process; + +complete_register: + process(clk) + begin + if rising_edge(clk) then + if start_en = '1' or rst = '1' then + complete <= '0'; + elsif complete = '0' then + if finish_en = '1' then + complete <= '1'; + elsif req_complete_ack = '1' then + complete <= '0'; + end if; + end if; + end if; + end process; + +end Behavioral; diff --git a/lib/JBUS/src/tb_busmaster_async.vhd b/lib/JBUS/src/tb_busmaster_async.vhd index 353d7d8..b73f53d 100644 --- a/lib/JBUS/src/tb_busmaster_async.vhd +++ b/lib/JBUS/src/tb_busmaster_async.vhd @@ -1,451 +1,451 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/tb_busmaster_async.vhd,v 1.1 2013-07-21 09:21:30 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY ieee; -use IEEE.STD_LOGIC_1164.ALL; -USE ieee.numeric_std.ALL; - -use work.busmaster_types.all; - -ENTITY tb_busmaster_async IS -END tb_busmaster_async; - -ARCHITECTURE behavior OF tb_busmaster_async IS - - constant DATA_WIDTH : integer := 32; - constant CLK_PERIOD : time := 10 ns; - constant JBUS_CLK_PERIOD : time := 20 ns; - signal clk : std_logic := '1'; - signal rst : std_logic := '1'; - - signal CLK_O : std_logic := '1'; - signal RST_O : std_logic := '1'; - - -- Master - signal INT_O : std_logic; - signal CYC_O : std_logic; - signal STB_O : std_logic; - signal WE_O : std_logic; - signal SEL_O : unsigned(3 downto 0) := (others => '1'); - signal ACK_I : std_logic := '0'; - signal MRDY_O : std_logic := '1'; - signal SRDY_I : std_logic := '0'; - signal ADDR_O : unsigned(31 downto 0) := (others => '-'); - signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); - signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); - - signal MDAT_I : unsigned(31 downto 0) := (others => '-'); - signal MDAT_O : unsigned(31 downto 0) := (others => '-'); - - signal cmd_cycle_finished : std_logic; - signal cmd_cycle_en : std_logic := '0'; - signal cmd_rdy : std_logic; - signal cmd_we : std_logic := '0'; - - signal cmd_in : bm_cmd_t; - - signal din : unsigned(31 downto 0) := (others => '-'); - signal din_rdy : std_logic; - signal din_we : std_logic := '0'; - - signal dout : unsigned(31 downto 0); - signal dout_vld : std_logic; - signal dout_re : std_logic := '0'; - - signal read_reg : unsigned(31 downto 0) := (others => '-'); - - type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); - signal state : state_t := IDLE; - - type ram_t is array (0 to 127) of unsigned(63 downto 0); - - signal ram64 : ram_t := - ( - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000" - - ); - -BEGIN - - MDAT_I <= MDAT_I_64(31 downto 0); - MDAT_O_64 <= MDAT_O & MDAT_O; - -inst_uut : entity work.busmaster_async - GENERIC MAP - ( - DATA_WIDTH => 32, - FIFO_DEPTH => 2 - ) - PORT MAP - ( - -- System signals - rst => rst, - clk => clk, - - cmd_cycle_finished => cmd_cycle_finished, - cmd_cycle_en => cmd_cycle_en, - cmd_rdy => cmd_rdy, - cmd_we => cmd_we, - cmd_in => cmd_in, - - din => din, - din_rdy => din_rdy, - din_we => din_we, - - dout => dout, - dout_vld => dout_vld, - dout_re => dout_re, - - -- JBUS Master signals - RST_I => RST_O, - CLK_I => CLK_O, - CYC_O => CYC_O, - STB_O => STB_O, - WE_O => WE_O, - SEL_O => SEL_O, - ACK_I => ACK_I, - SRDY_I => SRDY_I, - MRDY_O => MRDY_O, - ADDR_O => ADDR_O, - MDAT_I => MDAT_I, - MDAT_O => MDAT_O - ); - -CLK_GEN: process - begin - wait for CLK_PERIOD/2; - clk <= not clk; - end process; - -JBUS_CLK_GEN: process - begin - wait for JBUS_CLK_PERIOD/2; - CLK_O <= not CLK_O; - end process; - --- Slave - SRDY_I <= CYC_O; - - process(CLK_O) - variable res: unsigned(63 downto 0); - variable ram_data : unsigned(63 downto 0); - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - else - ACK_I <= '0'; - if (CYC_O and STB_O) = '1' then - if WE_O = '0' then - ACK_I <= '1'; - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - if ADDR_O(2) = '0' then - res := ram_data; - else - res := ram_data(31 downto 0) & ram_data(63 downto 32); - end if; - elsif MRDY_O = '1' then -- WE=1 - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - ram_data := (others => '-'); - if ADDR_O(2) = '0' then - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); - end if; - else - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); - end if; - end if; - end if; - end if; - if (CYC_O and MRDY_O) = '1' then - MDAT_I_64 <= res; - end if; - end if; - end if; - end process; - - process(clk) - begin - if rising_edge(clk) then - if rst = '1' then - read_reg <= X"00000000"; - elsif dout_vld = '1' then - read_reg <= dout; - end if; - end if; - end process; - dout_re <= dout_vld; - --- Master -STIMULUS: process - - variable result : unsigned(31 downto 0); - - procedure cmd_write_single(addr, sel, data : unsigned) is - begin - - din <= data; - din_we <= '1'; - wait until rising_edge(clk) and din_rdy = '1'; - din_we <= '0'; - - cmd_in.rw <= '1'; - cmd_in.sel <= sel; - cmd_in.addr <= addr; - cmd_we <= '1'; - wait until rising_edge(clk) and cmd_rdy = '1'; - cmd_we <= '0'; - - end procedure cmd_write_single; - - procedure cmd_read_single(addr : unsigned) is - begin - - cmd_in.rw <= '0'; - cmd_in.sel <= (others => '0'); - cmd_in.addr <= addr; - cmd_we <= '1'; - wait until rising_edge(clk) and cmd_rdy = '1'; - cmd_we <= '0'; - - end procedure cmd_read_single; - - begin - - wait for 6*CLK_PERIOD; - rst <= '0'; - RST_O <= '0'; - wait for 60*CLK_PERIOD; - wait until rising_edge(clk); - state <= IDLE; - - for i in 0 to 9 loop - - cmd_cycle_en <= '1'; - cmd_write_single(X"0000_0000", "1111", X"1000_ABCD"); - cmd_write_single(X"0000_0008", "1111", X"2000_ABCD"); - cmd_write_single(X"0000_0010", "1111", X"3000_ABCD"); - cmd_write_single(X"0000_0018", "1111", X"4000_ABCD"); - cmd_write_single(X"0000_0020", "1111", X"5000_ABCD"); - cmd_write_single(X"0000_0028", "1111", X"6000_ABCD"); - cmd_write_single(X"0000_0030", "1111", X"7000_ABCD"); - cmd_write_single(X"0000_0038", "1111", X"8000_ABCD"); - cmd_read_single(X"0000_0000"); - cmd_read_single(X"0000_0008"); - cmd_read_single(X"0000_0010"); - cmd_read_single(X"0000_0018"); - cmd_read_single(X"0000_0020"); - cmd_read_single(X"0000_0028"); - cmd_read_single(X"0000_0030"); - cmd_read_single(X"0000_0038"); - cmd_write_single(X"0000_0000", "1111", X"1000_BEEF"); - cmd_read_single(X"0000_0000"); - cmd_write_single(X"0000_0008", "1111", X"2000_BEEF"); - cmd_read_single(X"0000_0008"); - cmd_write_single(X"0000_0010", "1111", X"3000_BEEF"); - cmd_read_single(X"0000_0010"); - cmd_write_single(X"0000_0018", "1111", X"4000_BEEF"); - cmd_read_single(X"0000_0018"); - cmd_write_single(X"0000_0020", "1111", X"5000_BEEF"); - cmd_read_single(X"0000_0020"); - cmd_write_single(X"0000_0028", "1111", X"6000_BEEF"); - cmd_read_single(X"0000_0028"); - cmd_write_single(X"0000_0030", "1111", X"7000_BEEF"); - cmd_read_single(X"0000_0030"); - cmd_write_single(X"0000_0038", "1111", X"8000_BEEF"); - cmd_read_single(X"0000_0038"); - cmd_cycle_en <= '0'; - wait until rising_edge(clk); - wait until rising_edge(clk); - cmd_cycle_en <= '1'; - cmd_write_single(X"0000_0100", "1111", X"1100_ABCD"); - cmd_write_single(X"0000_0108", "1111", X"2200_ABCD"); - cmd_write_single(X"0000_0110", "1111", X"3300_ABCD"); - cmd_write_single(X"0000_0118", "1111", X"4400_ABCD"); - cmd_write_single(X"0000_0120", "1111", X"5500_ABCD"); - cmd_write_single(X"0000_0128", "1111", X"6600_ABCD"); - cmd_write_single(X"0000_0130", "1111", X"7700_ABCD"); - cmd_write_single(X"0000_0138", "1111", X"8800_ABCD"); - cmd_read_single(X"0000_0100"); - cmd_read_single(X"0000_0108"); - cmd_read_single(X"0000_0110"); - cmd_read_single(X"0000_0118"); - cmd_read_single(X"0000_0120"); - cmd_read_single(X"0000_0128"); - cmd_read_single(X"0000_0130"); - cmd_read_single(X"0000_0138"); - cmd_write_single(X"0000_0100", "1111", X"1100_BEEF"); - cmd_read_single(X"0000_0100"); - cmd_write_single(X"0000_0108", "1111", X"2200_BEEF"); - cmd_read_single(X"0000_0108"); - cmd_write_single(X"0000_0110", "1111", X"3300_BEEF"); - cmd_read_single(X"0000_0110"); - cmd_write_single(X"0000_0118", "1111", X"4400_BEEF"); - cmd_read_single(X"0000_0118"); - cmd_write_single(X"0000_0120", "1111", X"5500_BEEF"); - cmd_read_single(X"0000_0120"); - cmd_write_single(X"0000_0128", "1111", X"6600_BEEF"); - cmd_read_single(X"0000_0128"); - cmd_write_single(X"0000_0130", "1111", X"7700_BEEF"); - cmd_read_single(X"0000_0130"); - cmd_write_single(X"0000_0138", "1111", X"8800_BEEF"); - cmd_read_single(X"0000_0138"); - cmd_cycle_en <= '0'; - - wait until rising_edge(clk) and cmd_cycle_finished = '1'; - wait for 60*CLK_PERIOD; - wait until rising_edge(clk); - - end loop; - - state <= IDLE; - - wait; - - end process; - -END; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/tb_busmaster_async.vhd,v 1.1 2013/07/21 09:21:30 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; + +use work.busmaster_types.all; + +ENTITY tb_busmaster_async IS +END tb_busmaster_async; + +ARCHITECTURE behavior OF tb_busmaster_async IS + + constant DATA_WIDTH : integer := 32; + constant CLK_PERIOD : time := 10 ns; + constant JBUS_CLK_PERIOD : time := 20 ns; + signal clk : std_logic := '1'; + signal rst : std_logic := '1'; + + signal CLK_O : std_logic := '1'; + signal RST_O : std_logic := '1'; + + -- Master + signal INT_O : std_logic; + signal CYC_O : std_logic; + signal STB_O : std_logic; + signal WE_O : std_logic; + signal SEL_O : unsigned(3 downto 0) := (others => '1'); + signal ACK_I : std_logic := '0'; + signal MRDY_O : std_logic := '1'; + signal SRDY_I : std_logic := '0'; + signal ADDR_O : unsigned(31 downto 0) := (others => '-'); + signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); + signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); + + signal MDAT_I : unsigned(31 downto 0) := (others => '-'); + signal MDAT_O : unsigned(31 downto 0) := (others => '-'); + + signal cmd_cycle_finished : std_logic; + signal cmd_cycle_en : std_logic := '0'; + signal cmd_rdy : std_logic; + signal cmd_we : std_logic := '0'; + + signal cmd_in : bm_cmd_t; + + signal din : unsigned(31 downto 0) := (others => '-'); + signal din_rdy : std_logic; + signal din_we : std_logic := '0'; + + signal dout : unsigned(31 downto 0); + signal dout_vld : std_logic; + signal dout_re : std_logic := '0'; + + signal read_reg : unsigned(31 downto 0) := (others => '-'); + + type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); + signal state : state_t := IDLE; + + type ram_t is array (0 to 127) of unsigned(63 downto 0); + + signal ram64 : ram_t := + ( + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000" + + ); + +BEGIN + + MDAT_I <= MDAT_I_64(31 downto 0); + MDAT_O_64 <= MDAT_O & MDAT_O; + +inst_uut : entity work.busmaster_async + GENERIC MAP + ( + DATA_WIDTH => 32, + FIFO_DEPTH => 2 + ) + PORT MAP + ( + -- System signals + rst => rst, + clk => clk, + + cmd_cycle_finished => cmd_cycle_finished, + cmd_cycle_en => cmd_cycle_en, + cmd_rdy => cmd_rdy, + cmd_we => cmd_we, + cmd_in => cmd_in, + + din => din, + din_rdy => din_rdy, + din_we => din_we, + + dout => dout, + dout_vld => dout_vld, + dout_re => dout_re, + + -- JBUS Master signals + RST_I => RST_O, + CLK_I => CLK_O, + CYC_O => CYC_O, + STB_O => STB_O, + WE_O => WE_O, + SEL_O => SEL_O, + ACK_I => ACK_I, + SRDY_I => SRDY_I, + MRDY_O => MRDY_O, + ADDR_O => ADDR_O, + MDAT_I => MDAT_I, + MDAT_O => MDAT_O + ); + +CLK_GEN: process + begin + wait for CLK_PERIOD/2; + clk <= not clk; + end process; + +JBUS_CLK_GEN: process + begin + wait for JBUS_CLK_PERIOD/2; + CLK_O <= not CLK_O; + end process; + +-- Slave + SRDY_I <= CYC_O; + + process(CLK_O) + variable res: unsigned(63 downto 0); + variable ram_data : unsigned(63 downto 0); + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + else + ACK_I <= '0'; + if (CYC_O and STB_O) = '1' then + if WE_O = '0' then + ACK_I <= '1'; + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + if ADDR_O(2) = '0' then + res := ram_data; + else + res := ram_data(31 downto 0) & ram_data(63 downto 32); + end if; + elsif MRDY_O = '1' then -- WE=1 + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + ram_data := (others => '-'); + if ADDR_O(2) = '0' then + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); + end if; + else + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); + end if; + end if; + end if; + end if; + if (CYC_O and MRDY_O) = '1' then + MDAT_I_64 <= res; + end if; + end if; + end if; + end process; + + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + read_reg <= X"00000000"; + elsif dout_vld = '1' then + read_reg <= dout; + end if; + end if; + end process; + dout_re <= dout_vld; + +-- Master +STIMULUS: process + + variable result : unsigned(31 downto 0); + + procedure cmd_write_single(addr, sel, data : unsigned) is + begin + + din <= data; + din_we <= '1'; + wait until rising_edge(clk) and din_rdy = '1'; + din_we <= '0'; + + cmd_in.rw <= '1'; + cmd_in.sel <= sel; + cmd_in.addr <= addr; + cmd_we <= '1'; + wait until rising_edge(clk) and cmd_rdy = '1'; + cmd_we <= '0'; + + end procedure cmd_write_single; + + procedure cmd_read_single(addr : unsigned) is + begin + + cmd_in.rw <= '0'; + cmd_in.sel <= (others => '0'); + cmd_in.addr <= addr; + cmd_we <= '1'; + wait until rising_edge(clk) and cmd_rdy = '1'; + cmd_we <= '0'; + + end procedure cmd_read_single; + + begin + + wait for 6*CLK_PERIOD; + rst <= '0'; + RST_O <= '0'; + wait for 60*CLK_PERIOD; + wait until rising_edge(clk); + state <= IDLE; + + for i in 0 to 9 loop + + cmd_cycle_en <= '1'; + cmd_write_single(X"0000_0000", "1111", X"1000_ABCD"); + cmd_write_single(X"0000_0008", "1111", X"2000_ABCD"); + cmd_write_single(X"0000_0010", "1111", X"3000_ABCD"); + cmd_write_single(X"0000_0018", "1111", X"4000_ABCD"); + cmd_write_single(X"0000_0020", "1111", X"5000_ABCD"); + cmd_write_single(X"0000_0028", "1111", X"6000_ABCD"); + cmd_write_single(X"0000_0030", "1111", X"7000_ABCD"); + cmd_write_single(X"0000_0038", "1111", X"8000_ABCD"); + cmd_read_single(X"0000_0000"); + cmd_read_single(X"0000_0008"); + cmd_read_single(X"0000_0010"); + cmd_read_single(X"0000_0018"); + cmd_read_single(X"0000_0020"); + cmd_read_single(X"0000_0028"); + cmd_read_single(X"0000_0030"); + cmd_read_single(X"0000_0038"); + cmd_write_single(X"0000_0000", "1111", X"1000_BEEF"); + cmd_read_single(X"0000_0000"); + cmd_write_single(X"0000_0008", "1111", X"2000_BEEF"); + cmd_read_single(X"0000_0008"); + cmd_write_single(X"0000_0010", "1111", X"3000_BEEF"); + cmd_read_single(X"0000_0010"); + cmd_write_single(X"0000_0018", "1111", X"4000_BEEF"); + cmd_read_single(X"0000_0018"); + cmd_write_single(X"0000_0020", "1111", X"5000_BEEF"); + cmd_read_single(X"0000_0020"); + cmd_write_single(X"0000_0028", "1111", X"6000_BEEF"); + cmd_read_single(X"0000_0028"); + cmd_write_single(X"0000_0030", "1111", X"7000_BEEF"); + cmd_read_single(X"0000_0030"); + cmd_write_single(X"0000_0038", "1111", X"8000_BEEF"); + cmd_read_single(X"0000_0038"); + cmd_cycle_en <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + cmd_cycle_en <= '1'; + cmd_write_single(X"0000_0100", "1111", X"1100_ABCD"); + cmd_write_single(X"0000_0108", "1111", X"2200_ABCD"); + cmd_write_single(X"0000_0110", "1111", X"3300_ABCD"); + cmd_write_single(X"0000_0118", "1111", X"4400_ABCD"); + cmd_write_single(X"0000_0120", "1111", X"5500_ABCD"); + cmd_write_single(X"0000_0128", "1111", X"6600_ABCD"); + cmd_write_single(X"0000_0130", "1111", X"7700_ABCD"); + cmd_write_single(X"0000_0138", "1111", X"8800_ABCD"); + cmd_read_single(X"0000_0100"); + cmd_read_single(X"0000_0108"); + cmd_read_single(X"0000_0110"); + cmd_read_single(X"0000_0118"); + cmd_read_single(X"0000_0120"); + cmd_read_single(X"0000_0128"); + cmd_read_single(X"0000_0130"); + cmd_read_single(X"0000_0138"); + cmd_write_single(X"0000_0100", "1111", X"1100_BEEF"); + cmd_read_single(X"0000_0100"); + cmd_write_single(X"0000_0108", "1111", X"2200_BEEF"); + cmd_read_single(X"0000_0108"); + cmd_write_single(X"0000_0110", "1111", X"3300_BEEF"); + cmd_read_single(X"0000_0110"); + cmd_write_single(X"0000_0118", "1111", X"4400_BEEF"); + cmd_read_single(X"0000_0118"); + cmd_write_single(X"0000_0120", "1111", X"5500_BEEF"); + cmd_read_single(X"0000_0120"); + cmd_write_single(X"0000_0128", "1111", X"6600_BEEF"); + cmd_read_single(X"0000_0128"); + cmd_write_single(X"0000_0130", "1111", X"7700_BEEF"); + cmd_read_single(X"0000_0130"); + cmd_write_single(X"0000_0138", "1111", X"8800_BEEF"); + cmd_read_single(X"0000_0138"); + cmd_cycle_en <= '0'; + + wait until rising_edge(clk) and cmd_cycle_finished = '1'; + wait for 60*CLK_PERIOD; + wait until rising_edge(clk); + + end loop; + + state <= IDLE; + + wait; + + end process; + +END; diff --git a/lib/JBUS/src/tb_busmaster_sync.vhd b/lib/JBUS/src/tb_busmaster_sync.vhd index 1e656f6..c349c6e 100644 --- a/lib/JBUS/src/tb_busmaster_sync.vhd +++ b/lib/JBUS/src/tb_busmaster_sync.vhd @@ -1,446 +1,446 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/tb_busmaster_sync.vhd,v 1.3 2013-07-21 09:10:13 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY ieee; -use IEEE.STD_LOGIC_1164.ALL; -USE ieee.numeric_std.ALL; - -use work.busmaster_types.all; - -ENTITY tb_busmaster_sync IS -END tb_busmaster_sync; - -ARCHITECTURE behavior OF tb_busmaster_sync IS - - constant DATA_WIDTH : integer := 32; - constant CLK_PERIOD : time := 10 ns; - signal CLK_O : std_logic := '1'; - signal RST_O : std_logic := '1'; - - -- Master - signal INT_O : std_logic; - signal CYC_O : std_logic; - signal STB_O : std_logic; - signal WE_O : std_logic; - signal SEL_O : unsigned(3 downto 0) := (others => '1'); - signal ACK_I : std_logic := '0'; - signal MRDY_O : std_logic := '1'; - signal SRDY_I : std_logic := '0'; - signal ADDR_O : unsigned(31 downto 0) := (others => '-'); - signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); - signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); - - signal MDAT_I : unsigned(31 downto 0) := (others => '-'); - signal MDAT_O : unsigned(31 downto 0) := (others => '-'); - - signal cmd_cycle_finished : std_logic; - signal cmd_cycle_en : std_logic := '0'; - signal cmd_rdy : std_logic; - signal cmd_we : std_logic := '0'; - - signal cmd_in : bm_cmd_t; - - signal din : unsigned(31 downto 0) := (others => '-'); - signal din_rdy : std_logic; - signal din_we : std_logic := '0'; - - signal dout : unsigned(31 downto 0); - signal dout_vld : std_logic; - signal dout_re : std_logic := '0'; - - signal rdy : std_logic := '0'; - signal read_reg : unsigned(31 downto 0) := (others => '-'); - - type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); - signal state : state_t := IDLE; - - type ram_t is array (0 to 127) of unsigned(63 downto 0); - - signal ram64 : ram_t := - ( - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000" - - ); - -BEGIN - - MDAT_I <= MDAT_I_64(31 downto 0); - MDAT_O_64 <= MDAT_O & MDAT_O; - -inst_uut : entity work.busmaster_sync - GENERIC MAP - ( - DATA_WIDTH => 32, - FIFO_DEPTH => 2 - ) - PORT MAP - ( - -- System signals - rst => RST_O, - clk => CLK_O, - - cmd_cycle_finished => cmd_cycle_finished, - cmd_cycle_en => cmd_cycle_en, - cmd_rdy => cmd_rdy, - cmd_we => cmd_we, - cmd_in => cmd_in, - - din => din, - din_rdy => din_rdy, - din_we => din_we, - - dout => dout, - dout_vld => dout_vld, - dout_re => dout_re, - - -- JBUS Master signals - CYC_O => CYC_O, - STB_O => STB_O, - WE_O => WE_O, - SEL_O => SEL_O, - ACK_I => ACK_I, - SRDY_I => SRDY_I, - MRDY_O => MRDY_O, - ADDR_O => ADDR_O, - MDAT_I => MDAT_I, - MDAT_O => MDAT_O - ); - -rdy_GEN: process - begin --- wait for 3*CLK_PERIOD/2; - wait until rising_edge(CLK_O); - rdy <= not rdy; - end process; - -CLK_GEN: process - begin - wait for CLK_PERIOD/2; - CLK_O <= not CLK_O; - end process; - --- Slave - SRDY_I <= CYC_O; - - process(CLK_O) - variable res: unsigned(63 downto 0); - variable ram_data : unsigned(63 downto 0); - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - else - ACK_I <= '0'; - if (CYC_O and STB_O) = '1' then - if WE_O = '0' then - ACK_I <= '1'; - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - if ADDR_O(2) = '0' then - res := ram_data; - else - res := ram_data(31 downto 0) & ram_data(63 downto 32); - end if; - elsif MRDY_O = '1' then -- WE=1 - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - ram_data := (others => '-'); - if ADDR_O(2) = '0' then - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); - end if; - else - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); - end if; - end if; - end if; - end if; - if (CYC_O and MRDY_O) = '1' then - MDAT_I_64 <= res; - end if; - end if; - end if; - end process; - - process(CLK_O) - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - read_reg <= X"00000000"; - elsif dout_vld = '1' then - read_reg <= dout; - end if; - end if; - end process; - dout_re <= dout_vld; - --- Master -STIMULUS: process - - variable result : unsigned(31 downto 0); - - procedure cmd_write_single(addr, sel, data : unsigned) is - begin - - din <= data; - din_we <= '1'; - wait until rising_edge(CLK_O) and din_rdy = '1'; - din_we <= '0'; - - cmd_in.rw <= '1'; - cmd_in.sel <= sel; - cmd_in.addr <= addr; - cmd_we <= '1'; - wait until rising_edge(CLK_O) and cmd_rdy = '1'; - cmd_we <= '0'; - - end procedure cmd_write_single; - - procedure cmd_read_single(addr : unsigned) is - begin - - cmd_in.rw <= '0'; - cmd_in.sel <= (others => '0'); - cmd_in.addr <= addr; - cmd_we <= '1'; - wait until rising_edge(CLK_O) and cmd_rdy = '1'; - cmd_we <= '0'; - - end procedure cmd_read_single; - - begin - - wait for 6*CLK_PERIOD; - RST_O <= '0'; - wait for 60*CLK_PERIOD; - wait until rising_edge(CLK_O); - state <= IDLE; - - for i in 0 to 9 loop - - cmd_cycle_en <= '1'; - cmd_write_single(X"0000_0000", "1111", X"1000_ABCD"); - cmd_write_single(X"0000_0008", "1111", X"2000_ABCD"); - cmd_write_single(X"0000_0010", "1111", X"3000_ABCD"); - cmd_write_single(X"0000_0018", "1111", X"4000_ABCD"); - cmd_write_single(X"0000_0020", "1111", X"5000_ABCD"); - cmd_write_single(X"0000_0028", "1111", X"6000_ABCD"); - cmd_write_single(X"0000_0030", "1111", X"7000_ABCD"); - cmd_write_single(X"0000_0038", "1111", X"8000_ABCD"); - cmd_read_single(X"0000_0000"); - cmd_read_single(X"0000_0008"); - cmd_read_single(X"0000_0010"); - cmd_read_single(X"0000_0018"); - cmd_read_single(X"0000_0020"); - cmd_read_single(X"0000_0028"); - cmd_read_single(X"0000_0030"); - cmd_read_single(X"0000_0038"); - cmd_write_single(X"0000_0000", "1111", X"1000_BEEF"); - cmd_read_single(X"0000_0000"); - cmd_write_single(X"0000_0008", "1111", X"2000_BEEF"); - cmd_read_single(X"0000_0008"); - cmd_write_single(X"0000_0010", "1111", X"3000_BEEF"); - cmd_read_single(X"0000_0010"); - cmd_write_single(X"0000_0018", "1111", X"4000_BEEF"); - cmd_read_single(X"0000_0018"); - cmd_write_single(X"0000_0020", "1111", X"5000_BEEF"); - cmd_read_single(X"0000_0020"); - cmd_write_single(X"0000_0028", "1111", X"6000_BEEF"); - cmd_read_single(X"0000_0028"); - cmd_write_single(X"0000_0030", "1111", X"7000_BEEF"); - cmd_read_single(X"0000_0030"); - cmd_write_single(X"0000_0038", "1111", X"8000_BEEF"); - cmd_read_single(X"0000_0038"); - cmd_cycle_en <= '0'; - wait until rising_edge(CLK_O); - wait until rising_edge(CLK_O); - cmd_cycle_en <= '1'; - cmd_write_single(X"0000_0100", "1111", X"1100_ABCD"); - cmd_write_single(X"0000_0108", "1111", X"2200_ABCD"); - cmd_write_single(X"0000_0110", "1111", X"3300_ABCD"); - cmd_write_single(X"0000_0118", "1111", X"4400_ABCD"); - cmd_write_single(X"0000_0120", "1111", X"5500_ABCD"); - cmd_write_single(X"0000_0128", "1111", X"6600_ABCD"); - cmd_write_single(X"0000_0130", "1111", X"7700_ABCD"); - cmd_write_single(X"0000_0138", "1111", X"8800_ABCD"); - cmd_read_single(X"0000_0100"); - cmd_read_single(X"0000_0108"); - cmd_read_single(X"0000_0110"); - cmd_read_single(X"0000_0118"); - cmd_read_single(X"0000_0120"); - cmd_read_single(X"0000_0128"); - cmd_read_single(X"0000_0130"); - cmd_read_single(X"0000_0138"); - cmd_write_single(X"0000_0100", "1111", X"1100_BEEF"); - cmd_read_single(X"0000_0100"); - cmd_write_single(X"0000_0108", "1111", X"2200_BEEF"); - cmd_read_single(X"0000_0108"); - cmd_write_single(X"0000_0110", "1111", X"3300_BEEF"); - cmd_read_single(X"0000_0110"); - cmd_write_single(X"0000_0118", "1111", X"4400_BEEF"); - cmd_read_single(X"0000_0118"); - cmd_write_single(X"0000_0120", "1111", X"5500_BEEF"); - cmd_read_single(X"0000_0120"); - cmd_write_single(X"0000_0128", "1111", X"6600_BEEF"); - cmd_read_single(X"0000_0128"); - cmd_write_single(X"0000_0130", "1111", X"7700_BEEF"); - cmd_read_single(X"0000_0130"); - cmd_write_single(X"0000_0138", "1111", X"8800_BEEF"); - cmd_read_single(X"0000_0138"); - cmd_cycle_en <= '0'; - - wait until rising_edge(CLK_O) and cmd_cycle_finished = '1'; - wait for 60*CLK_PERIOD; - wait until rising_edge(CLK_O); - - end loop; - - state <= IDLE; - - wait; - - end process; - -END; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/tb_busmaster_sync.vhd,v 1.3 2013/07/21 09:10:13 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; + +use work.busmaster_types.all; + +ENTITY tb_busmaster_sync IS +END tb_busmaster_sync; + +ARCHITECTURE behavior OF tb_busmaster_sync IS + + constant DATA_WIDTH : integer := 32; + constant CLK_PERIOD : time := 10 ns; + signal CLK_O : std_logic := '1'; + signal RST_O : std_logic := '1'; + + -- Master + signal INT_O : std_logic; + signal CYC_O : std_logic; + signal STB_O : std_logic; + signal WE_O : std_logic; + signal SEL_O : unsigned(3 downto 0) := (others => '1'); + signal ACK_I : std_logic := '0'; + signal MRDY_O : std_logic := '1'; + signal SRDY_I : std_logic := '0'; + signal ADDR_O : unsigned(31 downto 0) := (others => '-'); + signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); + signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); + + signal MDAT_I : unsigned(31 downto 0) := (others => '-'); + signal MDAT_O : unsigned(31 downto 0) := (others => '-'); + + signal cmd_cycle_finished : std_logic; + signal cmd_cycle_en : std_logic := '0'; + signal cmd_rdy : std_logic; + signal cmd_we : std_logic := '0'; + + signal cmd_in : bm_cmd_t; + + signal din : unsigned(31 downto 0) := (others => '-'); + signal din_rdy : std_logic; + signal din_we : std_logic := '0'; + + signal dout : unsigned(31 downto 0); + signal dout_vld : std_logic; + signal dout_re : std_logic := '0'; + + signal rdy : std_logic := '0'; + signal read_reg : unsigned(31 downto 0) := (others => '-'); + + type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); + signal state : state_t := IDLE; + + type ram_t is array (0 to 127) of unsigned(63 downto 0); + + signal ram64 : ram_t := + ( + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000" + + ); + +BEGIN + + MDAT_I <= MDAT_I_64(31 downto 0); + MDAT_O_64 <= MDAT_O & MDAT_O; + +inst_uut : entity work.busmaster_sync + GENERIC MAP + ( + DATA_WIDTH => 32, + FIFO_DEPTH => 2 + ) + PORT MAP + ( + -- System signals + rst => RST_O, + clk => CLK_O, + + cmd_cycle_finished => cmd_cycle_finished, + cmd_cycle_en => cmd_cycle_en, + cmd_rdy => cmd_rdy, + cmd_we => cmd_we, + cmd_in => cmd_in, + + din => din, + din_rdy => din_rdy, + din_we => din_we, + + dout => dout, + dout_vld => dout_vld, + dout_re => dout_re, + + -- JBUS Master signals + CYC_O => CYC_O, + STB_O => STB_O, + WE_O => WE_O, + SEL_O => SEL_O, + ACK_I => ACK_I, + SRDY_I => SRDY_I, + MRDY_O => MRDY_O, + ADDR_O => ADDR_O, + MDAT_I => MDAT_I, + MDAT_O => MDAT_O + ); + +rdy_GEN: process + begin +-- wait for 3*CLK_PERIOD/2; + wait until rising_edge(CLK_O); + rdy <= not rdy; + end process; + +CLK_GEN: process + begin + wait for CLK_PERIOD/2; + CLK_O <= not CLK_O; + end process; + +-- Slave + SRDY_I <= CYC_O; + + process(CLK_O) + variable res: unsigned(63 downto 0); + variable ram_data : unsigned(63 downto 0); + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + else + ACK_I <= '0'; + if (CYC_O and STB_O) = '1' then + if WE_O = '0' then + ACK_I <= '1'; + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + if ADDR_O(2) = '0' then + res := ram_data; + else + res := ram_data(31 downto 0) & ram_data(63 downto 32); + end if; + elsif MRDY_O = '1' then -- WE=1 + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + ram_data := (others => '-'); + if ADDR_O(2) = '0' then + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); + end if; + else + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); + end if; + end if; + end if; + end if; + if (CYC_O and MRDY_O) = '1' then + MDAT_I_64 <= res; + end if; + end if; + end if; + end process; + + process(CLK_O) + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + read_reg <= X"00000000"; + elsif dout_vld = '1' then + read_reg <= dout; + end if; + end if; + end process; + dout_re <= dout_vld; + +-- Master +STIMULUS: process + + variable result : unsigned(31 downto 0); + + procedure cmd_write_single(addr, sel, data : unsigned) is + begin + + din <= data; + din_we <= '1'; + wait until rising_edge(CLK_O) and din_rdy = '1'; + din_we <= '0'; + + cmd_in.rw <= '1'; + cmd_in.sel <= sel; + cmd_in.addr <= addr; + cmd_we <= '1'; + wait until rising_edge(CLK_O) and cmd_rdy = '1'; + cmd_we <= '0'; + + end procedure cmd_write_single; + + procedure cmd_read_single(addr : unsigned) is + begin + + cmd_in.rw <= '0'; + cmd_in.sel <= (others => '0'); + cmd_in.addr <= addr; + cmd_we <= '1'; + wait until rising_edge(CLK_O) and cmd_rdy = '1'; + cmd_we <= '0'; + + end procedure cmd_read_single; + + begin + + wait for 6*CLK_PERIOD; + RST_O <= '0'; + wait for 60*CLK_PERIOD; + wait until rising_edge(CLK_O); + state <= IDLE; + + for i in 0 to 9 loop + + cmd_cycle_en <= '1'; + cmd_write_single(X"0000_0000", "1111", X"1000_ABCD"); + cmd_write_single(X"0000_0008", "1111", X"2000_ABCD"); + cmd_write_single(X"0000_0010", "1111", X"3000_ABCD"); + cmd_write_single(X"0000_0018", "1111", X"4000_ABCD"); + cmd_write_single(X"0000_0020", "1111", X"5000_ABCD"); + cmd_write_single(X"0000_0028", "1111", X"6000_ABCD"); + cmd_write_single(X"0000_0030", "1111", X"7000_ABCD"); + cmd_write_single(X"0000_0038", "1111", X"8000_ABCD"); + cmd_read_single(X"0000_0000"); + cmd_read_single(X"0000_0008"); + cmd_read_single(X"0000_0010"); + cmd_read_single(X"0000_0018"); + cmd_read_single(X"0000_0020"); + cmd_read_single(X"0000_0028"); + cmd_read_single(X"0000_0030"); + cmd_read_single(X"0000_0038"); + cmd_write_single(X"0000_0000", "1111", X"1000_BEEF"); + cmd_read_single(X"0000_0000"); + cmd_write_single(X"0000_0008", "1111", X"2000_BEEF"); + cmd_read_single(X"0000_0008"); + cmd_write_single(X"0000_0010", "1111", X"3000_BEEF"); + cmd_read_single(X"0000_0010"); + cmd_write_single(X"0000_0018", "1111", X"4000_BEEF"); + cmd_read_single(X"0000_0018"); + cmd_write_single(X"0000_0020", "1111", X"5000_BEEF"); + cmd_read_single(X"0000_0020"); + cmd_write_single(X"0000_0028", "1111", X"6000_BEEF"); + cmd_read_single(X"0000_0028"); + cmd_write_single(X"0000_0030", "1111", X"7000_BEEF"); + cmd_read_single(X"0000_0030"); + cmd_write_single(X"0000_0038", "1111", X"8000_BEEF"); + cmd_read_single(X"0000_0038"); + cmd_cycle_en <= '0'; + wait until rising_edge(CLK_O); + wait until rising_edge(CLK_O); + cmd_cycle_en <= '1'; + cmd_write_single(X"0000_0100", "1111", X"1100_ABCD"); + cmd_write_single(X"0000_0108", "1111", X"2200_ABCD"); + cmd_write_single(X"0000_0110", "1111", X"3300_ABCD"); + cmd_write_single(X"0000_0118", "1111", X"4400_ABCD"); + cmd_write_single(X"0000_0120", "1111", X"5500_ABCD"); + cmd_write_single(X"0000_0128", "1111", X"6600_ABCD"); + cmd_write_single(X"0000_0130", "1111", X"7700_ABCD"); + cmd_write_single(X"0000_0138", "1111", X"8800_ABCD"); + cmd_read_single(X"0000_0100"); + cmd_read_single(X"0000_0108"); + cmd_read_single(X"0000_0110"); + cmd_read_single(X"0000_0118"); + cmd_read_single(X"0000_0120"); + cmd_read_single(X"0000_0128"); + cmd_read_single(X"0000_0130"); + cmd_read_single(X"0000_0138"); + cmd_write_single(X"0000_0100", "1111", X"1100_BEEF"); + cmd_read_single(X"0000_0100"); + cmd_write_single(X"0000_0108", "1111", X"2200_BEEF"); + cmd_read_single(X"0000_0108"); + cmd_write_single(X"0000_0110", "1111", X"3300_BEEF"); + cmd_read_single(X"0000_0110"); + cmd_write_single(X"0000_0118", "1111", X"4400_BEEF"); + cmd_read_single(X"0000_0118"); + cmd_write_single(X"0000_0120", "1111", X"5500_BEEF"); + cmd_read_single(X"0000_0120"); + cmd_write_single(X"0000_0128", "1111", X"6600_BEEF"); + cmd_read_single(X"0000_0128"); + cmd_write_single(X"0000_0130", "1111", X"7700_BEEF"); + cmd_read_single(X"0000_0130"); + cmd_write_single(X"0000_0138", "1111", X"8800_BEEF"); + cmd_read_single(X"0000_0138"); + cmd_cycle_en <= '0'; + + wait until rising_edge(CLK_O) and cmd_cycle_finished = '1'; + wait for 60*CLK_PERIOD; + wait until rising_edge(CLK_O); + + end loop; + + state <= IDLE; + + wait; + + end process; + +END; diff --git a/lib/JBUS/src/tb_dmac.vhd b/lib/JBUS/src/tb_dmac.vhd index e22af1f..e42934b 100644 --- a/lib/JBUS/src/tb_dmac.vhd +++ b/lib/JBUS/src/tb_dmac.vhd @@ -1,540 +1,540 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/tb_dmac.vhd,v 1.2 2013-05-28 11:23:15 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY ieee; -use IEEE.STD_LOGIC_1164.ALL; -USE ieee.numeric_std.ALL; - -use work.busmaster_types.all; - -ENTITY tb_dmac IS -END tb_dmac; - -ARCHITECTURE behavior OF tb_dmac IS - - constant CLK_PERIOD : time := 10 ns; - constant DATA_WIDTH : integer := 32; - - constant DMA_NUM_CHANNEL : integer := 2; - constant DMA_CH_WRITE : integer := 0; - constant DMA_CH_READ : integer := 1; - constant DMA_RW_CONF : unsigned(DMA_NUM_CHANNEL-1 downto 0) := "01"; - - signal CLK_O : std_logic := '1'; - signal RST_O : std_logic := '1'; - - -- Master - signal CYC_O : std_logic; - signal STB_O : std_logic; - signal WE_O : std_logic; - signal SEL_O : unsigned(3 downto 0) := (others => '1'); - signal ACK_I : std_logic := '0'; - signal MRDY_O : std_logic := '1'; - signal SRDY_I : std_logic := '0'; - signal ADDR_O : unsigned(31 downto 0) := (others => '-'); - signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); - signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); - - signal MDAT_I : unsigned(31 downto 0) := (others => '-'); - signal MDAT_O : unsigned(31 downto 0) := (others => '-'); - - -- DMA controller - signal dma_master_req : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_master_gnt : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); - signal dma_req_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_req_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); - signal dma_req_addr_auto_inc : unsigned(DMA_NUM_CHANNEL-1 downto 0); - type array32_t is array (0 to DMA_NUM_CHANNEL-1) of unsigned(31 downto 0); - signal dma_req_addr : array32_t; - signal dma_req_num_xfers : array32_t; - - signal dma_req_complete : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_req_complete_ack : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); - - signal dma_start : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_active : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_end : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_bus_cmd_cycle_finished : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_bus_cmd_cycle_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); - signal dma_bus_cmd_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0); - signal dma_bus_cmd_we : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); - type array_bus_cmd_t is array (0 to DMA_NUM_CHANNEL-1) of bm_cmd_t; - signal dma_bus_cmd : array_bus_cmd_t; - - signal arb_idx : natural range 0 to DMA_NUM_CHANNEL-1; - - -- BUS Master controller - signal bus_din_re : std_logic; - signal bus_cmd_cycle_finished : std_logic; - signal bus_cmd_cycle_en : std_logic := '0'; - signal bus_cmd_rdy : std_logic; - signal bus_cmd_we : std_logic := '0'; - signal bus_cmd : bm_cmd_t; - - signal bus_din_rdy : std_logic; - signal bus_din_vld : std_logic := '0'; - signal bus_din : unsigned(DATA_WIDTH-1 downto 0) := (others => '-'); - - signal bus_dout : unsigned(31 downto 0); - signal bus_dout_vld : std_logic; - signal bus_dout_re : std_logic := '0'; - - signal rdy : std_logic := '0'; - signal read_reg : unsigned(31 downto 0) := (others => '-'); - - signal data_gen_reg : unsigned(31 downto 0) := (others => '-'); - signal data_gen_reg_inc : std_logic; - signal data_req : std_logic; - - type dma_write_source_t is (DATA_GEN, READ_FIFO); - signal dma_write_source : dma_write_source_t := DATA_GEN; - - -- Read FIFO - 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_din : unsigned(31 downto 0); - signal read_fifo_dout : unsigned(31 downto 0); - - type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); - signal state : state_t := IDLE; - - type ram_t is array (0 to 127) of unsigned(63 downto 0); - - signal ram64 : ram_t := - ( - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000", - X"0000_0000_0000_0000" - - ); - -BEGIN - - MDAT_I <= MDAT_I_64(31 downto 0); - MDAT_O_64 <= MDAT_O & MDAT_O; - -arbiter_proc: - process(CLK_O) - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - dma_master_gnt <= (others => '0'); - arb_idx <= 0; - elsif dma_master_req(arb_idx) = '0' then - if arb_idx /= DMA_NUM_CHANNEL-1 then - arb_idx <= arb_idx + 1; - else - arb_idx <= 0; - end if; - else - dma_master_gnt <= (others => '0'); - dma_master_gnt(arb_idx) <= '1'; - end if; - end if; - end process; - -arbiter_mux: - process(dma_master_gnt, dma_bus_cmd, dma_bus_cmd_we, dma_bus_cmd_cycle_en) - variable v_bus_cmd_we : std_logic; - variable v_bus_cmd_cycle_en : std_logic; - begin - v_bus_cmd_we := '0'; - v_bus_cmd_cycle_en := '0'; - for i in 0 to DMA_NUM_CHANNEL-1 loop - v_bus_cmd_we := v_bus_cmd_we or dma_bus_cmd_we(i); - v_bus_cmd_cycle_en := v_bus_cmd_cycle_en or dma_bus_cmd_cycle_en(i); - if dma_master_gnt(i) = '1' then - bus_cmd <= dma_bus_cmd(i); - end if; - end loop; - bus_cmd_we <= v_bus_cmd_we; - bus_cmd_cycle_en <= v_bus_cmd_cycle_en; -end process; - - -gen_uut: -for i in 0 to DMA_NUM_CHANNEL-1 generate - - dma_bus_cmd_cycle_finished(i) <= bus_cmd_cycle_finished; - dma_bus_cmd_rdy(i) <= bus_cmd_rdy; - - inst_uut : entity work.dmac - Generic map - ( - DATA_WIDTH => 32, - XFER_CHUNK_SIZE => 8 - ) - Port map - ( - clk => CLK_O, - rst => RST_O, - - master_req => dma_master_req(i), - master_gnt => dma_master_gnt(i), - - req_rdy => dma_req_rdy(i), - req_en => dma_req_en(i), - req_rw => DMA_RW_CONF(i), - req_addr_auto_inc => dma_req_addr_auto_inc(i), - req_addr_start => dma_req_addr(i), - req_num_xfers => dma_req_num_xfers(i), - - req_complete => dma_req_complete(i), - req_complete_ack => dma_req_complete_ack(i), - - dma_start => dma_start(i), - dma_active => dma_active(i), - dma_end => dma_end(i), - - -- busmaster control - bus_cyc_complete => dma_bus_cmd_cycle_finished(i), - bus_cmd_rdy => dma_bus_cmd_rdy(i), - bus_cmd_we => dma_bus_cmd_we(i), - bus_cmd_cycle_en => dma_bus_cmd_cycle_en(i), - - -- busmaster command - bus_cmd_out => dma_bus_cmd(i) - ); - -end generate; - --- Read buffer -inst_DMA_READ_FIFO: entity work.fifo_sync - GENERIC MAP - ( - addr_width => 10, - data_width => DATA_WIDTH, - do_last_read_update => true - ) - PORT MAP - ( - rst => RST_O, - clk => CLK_O, - 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 - ); - -inst_busmaster_sync : entity work.busmaster_sync - GENERIC MAP - ( - DATA_WIDTH => DATA_WIDTH, - FIFO_DEPTH => 4 - ) - PORT MAP - ( - -- System signals - rst => RST_O, - clk => CLK_O, - - cmd_cycle_finished => bus_cmd_cycle_finished, - cmd_cycle_en => bus_cmd_cycle_en, - - cmd_rdy => bus_cmd_rdy, - cmd_we => bus_cmd_we, - cmd_in => bus_cmd, - - din_rdy => bus_din_rdy, - din_we => bus_din_vld, - din => bus_din, - - dout => bus_dout, - dout_vld => bus_dout_vld, - dout_re => bus_dout_re, - - -- JBUS Master signals - CYC_O => CYC_O, - STB_O => STB_O, - WE_O => WE_O, - SEL_O => SEL_O, - ACK_I => ACK_I, - SRDY_I => SRDY_I, - MRDY_O => MRDY_O, - ADDR_O => ADDR_O, - MDAT_I => MDAT_I, - MDAT_O => MDAT_O - ); - -rdy_GEN: process - begin --- wait for 3*CLK_PERIOD/2; - wait until rising_edge(CLK_O); - rdy <= not rdy; - end process; - -CLK_GEN: process - begin - wait for CLK_PERIOD/2; - CLK_O <= not CLK_O; - end process; - --- Slave - SRDY_I <= CYC_O; - - bus_dout_re <= '1' when dma_write_source = DATA_GEN else not read_fifo_full; - bus_din_vld <= dma_active(DMA_CH_WRITE) when dma_write_source = DATA_GEN else (dma_active(DMA_CH_WRITE) and not read_fifo_empty); - bus_din <= data_gen_reg when dma_write_source = DATA_GEN else read_fifo_dout; - data_gen_reg_inc <= (bus_din_rdy and dma_active(DMA_CH_WRITE)) when dma_write_source = DATA_GEN else '0'; - read_fifo_re <= (bus_din_rdy and dma_active(DMA_CH_WRITE)) when dma_write_source = READ_FIFO else '0'; - read_fifo_we <= bus_dout_vld; - read_fifo_din <= bus_dout; - - process(CLK_O) - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - data_gen_reg <= X"BEEF_0000"; - elsif data_gen_reg_inc = '1' then - data_gen_reg <= data_gen_reg + X"0000_0004"; - end if; - end if; - end process; - - - process(CLK_O) - variable res: unsigned(63 downto 0); - variable ram_data : unsigned(63 downto 0); - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - else - ACK_I <= '0'; - if (CYC_O and STB_O) = '1' then - if WE_O = '0' then - ACK_I <= '1'; - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - if ADDR_O(2) = '0' then - res := ram_data; - else - res := ram_data(31 downto 0) & ram_data(63 downto 32); - end if; - else -- WE=1 - ram_data := ram64(to_integer(ADDR_O(31 downto 3))); - -- ram_data := (others => '-'); - if ADDR_O(2) = '0' then - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); - end if; - else - if SEL_O = "11111111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); - elsif SEL_O = "00001111" then - ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); - elsif SEL_O = "11110000" then - ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); - end if; - end if; - end if; - end if; - MDAT_I_64 <= res; - end if; - end if; - end process; - - process(CLK_O) - begin - if rising_edge(CLK_O) then - if RST_O = '1' then - read_reg <= X"00000000"; - elsif bus_dout_vld = '1' then - read_reg <= bus_dout; - end if; - end if; - end process; - - --- Master -STIMULUS: process - - procedure dma_wait_xfer_complete(ch : integer) is - begin - - dma_req_complete_ack(ch) <= '1'; - - wait until rising_edge(CLK_O) and dma_req_complete(ch) = '1'; - dma_req_complete_ack(ch) <= '0'; - - end procedure dma_wait_xfer_complete; - - procedure dma_request(ch : integer; addr_start, num_xfers : unsigned) is - begin - - dma_req_addr_auto_inc(ch) <= '1'; - dma_req_addr(ch) <= addr_start; - dma_req_num_xfers(ch) <= num_xfers; - - dma_req_en(ch) <= '1'; - - wait until rising_edge(CLK_O) and dma_req_rdy(ch) = '1'; - dma_req_en(ch) <= '0'; - - end procedure dma_request; - - begin - - wait for 6*CLK_PERIOD; - RST_O <= '0'; - wait for 60*CLK_PERIOD; - wait until rising_edge(CLK_O); - state <= IDLE; - - dma_request(DMA_CH_WRITE, X"00000000", X"00000040"); --- dma_wait_xfer_complete(DMA_CH_WRITE); - dma_request(DMA_CH_READ, X"00000000", X"00000040"); - dma_wait_xfer_complete(DMA_CH_READ); - dma_write_source <= READ_FIFO; - dma_request(DMA_CH_WRITE, X"00000100", X"00000040"); --- dma_wait_xfer_complete(DMA_CH_WRITE); - - state <= IDLE; - - wait; - - end process; - -END; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/tb_dmac.vhd,v 1.2 2013/05/28 11:23:15 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; + +use work.busmaster_types.all; + +ENTITY tb_dmac IS +END tb_dmac; + +ARCHITECTURE behavior OF tb_dmac IS + + constant CLK_PERIOD : time := 10 ns; + constant DATA_WIDTH : integer := 32; + + constant DMA_NUM_CHANNEL : integer := 2; + constant DMA_CH_WRITE : integer := 0; + constant DMA_CH_READ : integer := 1; + constant DMA_RW_CONF : unsigned(DMA_NUM_CHANNEL-1 downto 0) := "01"; + + signal CLK_O : std_logic := '1'; + signal RST_O : std_logic := '1'; + + -- Master + signal CYC_O : std_logic; + signal STB_O : std_logic; + signal WE_O : std_logic; + signal SEL_O : unsigned(3 downto 0) := (others => '1'); + signal ACK_I : std_logic := '0'; + signal MRDY_O : std_logic := '1'; + signal SRDY_I : std_logic := '0'; + signal ADDR_O : unsigned(31 downto 0) := (others => '-'); + signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-'); + signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-'); + + signal MDAT_I : unsigned(31 downto 0) := (others => '-'); + signal MDAT_O : unsigned(31 downto 0) := (others => '-'); + + -- DMA controller + signal dma_master_req : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_master_gnt : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); + signal dma_req_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_req_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); + signal dma_req_addr_auto_inc : unsigned(DMA_NUM_CHANNEL-1 downto 0); + type array32_t is array (0 to DMA_NUM_CHANNEL-1) of unsigned(31 downto 0); + signal dma_req_addr : array32_t; + signal dma_req_num_xfers : array32_t; + + signal dma_req_complete : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_req_complete_ack : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); + + signal dma_start : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_active : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_end : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_bus_cmd_cycle_finished : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_bus_cmd_cycle_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); + signal dma_bus_cmd_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0); + signal dma_bus_cmd_we : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0'); + type array_bus_cmd_t is array (0 to DMA_NUM_CHANNEL-1) of bm_cmd_t; + signal dma_bus_cmd : array_bus_cmd_t; + + signal arb_idx : natural range 0 to DMA_NUM_CHANNEL-1; + + -- BUS Master controller + signal bus_din_re : std_logic; + signal bus_cmd_cycle_finished : std_logic; + signal bus_cmd_cycle_en : std_logic := '0'; + signal bus_cmd_rdy : std_logic; + signal bus_cmd_we : std_logic := '0'; + signal bus_cmd : bm_cmd_t; + + signal bus_din_rdy : std_logic; + signal bus_din_vld : std_logic := '0'; + signal bus_din : unsigned(DATA_WIDTH-1 downto 0) := (others => '-'); + + signal bus_dout : unsigned(31 downto 0); + signal bus_dout_vld : std_logic; + signal bus_dout_re : std_logic := '0'; + + signal rdy : std_logic := '0'; + signal read_reg : unsigned(31 downto 0) := (others => '-'); + + signal data_gen_reg : unsigned(31 downto 0) := (others => '-'); + signal data_gen_reg_inc : std_logic; + signal data_req : std_logic; + + type dma_write_source_t is (DATA_GEN, READ_FIFO); + signal dma_write_source : dma_write_source_t := DATA_GEN; + + -- Read FIFO + 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_din : unsigned(31 downto 0); + signal read_fifo_dout : unsigned(31 downto 0); + + type state_t is (IDLE, LA_SA, LA_SU, LU_SA, LU_SU, CC_SA, CC_SU); + signal state : state_t := IDLE; + + type ram_t is array (0 to 127) of unsigned(63 downto 0); + + signal ram64 : ram_t := + ( + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000", + X"0000_0000_0000_0000" + + ); + +BEGIN + + MDAT_I <= MDAT_I_64(31 downto 0); + MDAT_O_64 <= MDAT_O & MDAT_O; + +arbiter_proc: + process(CLK_O) + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + dma_master_gnt <= (others => '0'); + arb_idx <= 0; + elsif dma_master_req(arb_idx) = '0' then + if arb_idx /= DMA_NUM_CHANNEL-1 then + arb_idx <= arb_idx + 1; + else + arb_idx <= 0; + end if; + else + dma_master_gnt <= (others => '0'); + dma_master_gnt(arb_idx) <= '1'; + end if; + end if; + end process; + +arbiter_mux: + process(dma_master_gnt, dma_bus_cmd, dma_bus_cmd_we, dma_bus_cmd_cycle_en) + variable v_bus_cmd_we : std_logic; + variable v_bus_cmd_cycle_en : std_logic; + begin + v_bus_cmd_we := '0'; + v_bus_cmd_cycle_en := '0'; + for i in 0 to DMA_NUM_CHANNEL-1 loop + v_bus_cmd_we := v_bus_cmd_we or dma_bus_cmd_we(i); + v_bus_cmd_cycle_en := v_bus_cmd_cycle_en or dma_bus_cmd_cycle_en(i); + if dma_master_gnt(i) = '1' then + bus_cmd <= dma_bus_cmd(i); + end if; + end loop; + bus_cmd_we <= v_bus_cmd_we; + bus_cmd_cycle_en <= v_bus_cmd_cycle_en; +end process; + + +gen_uut: +for i in 0 to DMA_NUM_CHANNEL-1 generate + + dma_bus_cmd_cycle_finished(i) <= bus_cmd_cycle_finished; + dma_bus_cmd_rdy(i) <= bus_cmd_rdy; + + inst_uut : entity work.dmac + Generic map + ( + DATA_WIDTH => 32, + XFER_CHUNK_SIZE => 8 + ) + Port map + ( + clk => CLK_O, + rst => RST_O, + + master_req => dma_master_req(i), + master_gnt => dma_master_gnt(i), + + req_rdy => dma_req_rdy(i), + req_en => dma_req_en(i), + req_rw => DMA_RW_CONF(i), + req_addr_auto_inc => dma_req_addr_auto_inc(i), + req_addr_start => dma_req_addr(i), + req_num_xfers => dma_req_num_xfers(i), + + req_complete => dma_req_complete(i), + req_complete_ack => dma_req_complete_ack(i), + + dma_start => dma_start(i), + dma_active => dma_active(i), + dma_end => dma_end(i), + + -- busmaster control + bus_cyc_complete => dma_bus_cmd_cycle_finished(i), + bus_cmd_rdy => dma_bus_cmd_rdy(i), + bus_cmd_we => dma_bus_cmd_we(i), + bus_cmd_cycle_en => dma_bus_cmd_cycle_en(i), + + -- busmaster command + bus_cmd_out => dma_bus_cmd(i) + ); + +end generate; + +-- Read buffer +inst_DMA_READ_FIFO: entity work.fifo_sync + GENERIC MAP + ( + addr_width => 10, + data_width => DATA_WIDTH, + do_last_read_update => true + ) + PORT MAP + ( + rst => RST_O, + clk => CLK_O, + 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 + ); + +inst_busmaster_sync : entity work.busmaster_sync + GENERIC MAP + ( + DATA_WIDTH => DATA_WIDTH, + FIFO_DEPTH => 4 + ) + PORT MAP + ( + -- System signals + rst => RST_O, + clk => CLK_O, + + cmd_cycle_finished => bus_cmd_cycle_finished, + cmd_cycle_en => bus_cmd_cycle_en, + + cmd_rdy => bus_cmd_rdy, + cmd_we => bus_cmd_we, + cmd_in => bus_cmd, + + din_rdy => bus_din_rdy, + din_we => bus_din_vld, + din => bus_din, + + dout => bus_dout, + dout_vld => bus_dout_vld, + dout_re => bus_dout_re, + + -- JBUS Master signals + CYC_O => CYC_O, + STB_O => STB_O, + WE_O => WE_O, + SEL_O => SEL_O, + ACK_I => ACK_I, + SRDY_I => SRDY_I, + MRDY_O => MRDY_O, + ADDR_O => ADDR_O, + MDAT_I => MDAT_I, + MDAT_O => MDAT_O + ); + +rdy_GEN: process + begin +-- wait for 3*CLK_PERIOD/2; + wait until rising_edge(CLK_O); + rdy <= not rdy; + end process; + +CLK_GEN: process + begin + wait for CLK_PERIOD/2; + CLK_O <= not CLK_O; + end process; + +-- Slave + SRDY_I <= CYC_O; + + bus_dout_re <= '1' when dma_write_source = DATA_GEN else not read_fifo_full; + bus_din_vld <= dma_active(DMA_CH_WRITE) when dma_write_source = DATA_GEN else (dma_active(DMA_CH_WRITE) and not read_fifo_empty); + bus_din <= data_gen_reg when dma_write_source = DATA_GEN else read_fifo_dout; + data_gen_reg_inc <= (bus_din_rdy and dma_active(DMA_CH_WRITE)) when dma_write_source = DATA_GEN else '0'; + read_fifo_re <= (bus_din_rdy and dma_active(DMA_CH_WRITE)) when dma_write_source = READ_FIFO else '0'; + read_fifo_we <= bus_dout_vld; + read_fifo_din <= bus_dout; + + process(CLK_O) + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + data_gen_reg <= X"BEEF_0000"; + elsif data_gen_reg_inc = '1' then + data_gen_reg <= data_gen_reg + X"0000_0004"; + end if; + end if; + end process; + + + process(CLK_O) + variable res: unsigned(63 downto 0); + variable ram_data : unsigned(63 downto 0); + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + else + ACK_I <= '0'; + if (CYC_O and STB_O) = '1' then + if WE_O = '0' then + ACK_I <= '1'; + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + if ADDR_O(2) = '0' then + res := ram_data; + else + res := ram_data(31 downto 0) & ram_data(63 downto 32); + end if; + else -- WE=1 + ram_data := ram64(to_integer(ADDR_O(31 downto 3))); + -- ram_data := (others => '-'); + if ADDR_O(2) = '0' then + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64; + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0); + end if; + else + if SEL_O = "11111111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32); + elsif SEL_O = "00001111" then + ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0); + elsif SEL_O = "11110000" then + ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32); + end if; + end if; + end if; + end if; + MDAT_I_64 <= res; + end if; + end if; + end process; + + process(CLK_O) + begin + if rising_edge(CLK_O) then + if RST_O = '1' then + read_reg <= X"00000000"; + elsif bus_dout_vld = '1' then + read_reg <= bus_dout; + end if; + end if; + end process; + + +-- Master +STIMULUS: process + + procedure dma_wait_xfer_complete(ch : integer) is + begin + + dma_req_complete_ack(ch) <= '1'; + + wait until rising_edge(CLK_O) and dma_req_complete(ch) = '1'; + dma_req_complete_ack(ch) <= '0'; + + end procedure dma_wait_xfer_complete; + + procedure dma_request(ch : integer; addr_start, num_xfers : unsigned) is + begin + + dma_req_addr_auto_inc(ch) <= '1'; + dma_req_addr(ch) <= addr_start; + dma_req_num_xfers(ch) <= num_xfers; + + dma_req_en(ch) <= '1'; + + wait until rising_edge(CLK_O) and dma_req_rdy(ch) = '1'; + dma_req_en(ch) <= '0'; + + end procedure dma_request; + + begin + + wait for 6*CLK_PERIOD; + RST_O <= '0'; + wait for 60*CLK_PERIOD; + wait until rising_edge(CLK_O); + state <= IDLE; + + dma_request(DMA_CH_WRITE, X"00000000", X"00000040"); +-- dma_wait_xfer_complete(DMA_CH_WRITE); + dma_request(DMA_CH_READ, X"00000000", X"00000040"); + dma_wait_xfer_complete(DMA_CH_READ); + dma_write_source <= READ_FIFO; + dma_request(DMA_CH_WRITE, X"00000100", X"00000040"); +-- dma_wait_xfer_complete(DMA_CH_WRITE); + + state <= IDLE; + + wait; + + end process; + +END; diff --git a/lib/PCK_FIO-2002.7/CHANGES b/lib/PCK_FIO-2002.7/CHANGES index b755a56..c7612e3 100644 --- a/lib/PCK_FIO-2002.7/CHANGES +++ b/lib/PCK_FIO-2002.7/CHANGES @@ -1,86 +1,86 @@ ----- $Id: CHANGES,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - -Changes from version 1.16 to version 2002.07 -============================================ - -PCK_FIO is now distributed under the GNU Lesser General Public Licencse -instead of the ordinary GPL, to better reflect intended usage. - -Cosmetic changes in source code to correct some typos in the testbench output. -A new testbench is also supplied. - -The package now uses IEEE.numeric_std as default. - -URL http://www.easics.com has been made part of address. - -Changed syntax in the PCK_FIO package and its testbench to support VHDL-1993. -Because of backwards-incompatibility, it has been necessary to supply -different sets of files for 1987 and 1993. - -Split the packages into a separate file for the header and a -separate file for the body (in compliance with Easics' guidelines). - -These changes resulted in the files: - -Files for VHDL-1993: --------------------- - PCK_FIO_1993.vhd : the source code of the header file for the package - PCK_FIO_1993_BODY.vhd: the source code of the body of the package - TB_PCK_FIO_1993.vhd: the testbench for the package - -Files for VHDL-1987: --------------------- - PCK_FIO_1987.vhd: the source code of the header file for the package - PCK_FIO_1987_BODY.vhd: the source code of the body of the package - TB_PCK_FIO_1987.vhd: the testbench for the package - -Updated README and PCK_FIO.html to support these changes. - -Adapted package files to support NUL termination of strings. -fo(Arg: string) now prints the string until the first NUL. -Several examples of its use are demonstrated in the supplied testbenches. - -Made cosmetic changes to code to improve readability. - -Acknowledgment --------------- -These changes have been implemented by Peter Geens. - - - - - - - - - - - - - +---- $Id: CHANGES,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + +Changes from version 1.16 to version 2002.07 +============================================ + +PCK_FIO is now distributed under the GNU Lesser General Public Licencse +instead of the ordinary GPL, to better reflect intended usage. + +Cosmetic changes in source code to correct some typos in the testbench output. +A new testbench is also supplied. + +The package now uses IEEE.numeric_std as default. + +URL http://www.easics.com has been made part of address. + +Changed syntax in the PCK_FIO package and its testbench to support VHDL-1993. +Because of backwards-incompatibility, it has been necessary to supply +different sets of files for 1987 and 1993. + +Split the packages into a separate file for the header and a +separate file for the body (in compliance with Easics' guidelines). + +These changes resulted in the files: + +Files for VHDL-1993: +-------------------- + PCK_FIO_1993.vhd : the source code of the header file for the package + PCK_FIO_1993_BODY.vhd: the source code of the body of the package + TB_PCK_FIO_1993.vhd: the testbench for the package + +Files for VHDL-1987: +-------------------- + PCK_FIO_1987.vhd: the source code of the header file for the package + PCK_FIO_1987_BODY.vhd: the source code of the body of the package + TB_PCK_FIO_1987.vhd: the testbench for the package + +Updated README and PCK_FIO.html to support these changes. + +Adapted package files to support NUL termination of strings. +fo(Arg: string) now prints the string until the first NUL. +Several examples of its use are demonstrated in the supplied testbenches. + +Made cosmetic changes to code to improve readability. + +Acknowledgment +-------------- +These changes have been implemented by Peter Geens. + + + + + + + + + + + + + diff --git a/lib/PCK_FIO-2002.7/PCK_FIO.html b/lib/PCK_FIO-2002.7/PCK_FIO.html index 6b5fc72..fe085cd 100644 --- a/lib/PCK_FIO-2002.7/PCK_FIO.html +++ b/lib/PCK_FIO-2002.7/PCK_FIO.html @@ -1,339 +1,339 @@ - - - - - - VHDL package for formatted file output - - - - -
-

-Name

-PCK_FIO - VHDL package for  formatted file output -

-


-

-Contents

-Usage -
The file output function 'fo' -
Format specifiers -
Special characters -
Things to watch out for -
Methodology notes -
Parametrization -
Test bench -
Known limitations and problems -
Author -

-


-

-Usage

-PCK_FIO is a VHDL package that defines  fprint, a function -for formatted file output. -

After installing the package you can call fprint as follows: -

  fprint(F, L, Format, fo(Expr_1), fo(Expr_2), ... fo(Expr_n));
-where F is the filehandle and L is the line variable. -

The argument Format is the format string, which consists of ``normal'' -substrings which are copied verbatim, and format specifiers, starting with -'%'. -A typical format string looks as follows: -

   "Arg1 = %6r, Arg2 = %10d, Arg3 = %-5r\n"
-The remaining arguments are the expressions whose results you want to write -to the file, embedded in fo function calls. There can be 0 to -32 of such arguments. The expressions can be of any type for which an fo -function exists. String expressions can also be called directly. -

-


-

-The file output function 'fo'

-The fo (file output) functions do the trick. They -return a tagged string representation that is meaningful to format specifiers. -Here are some examples: -
  fo (signed'("1100"))   returns "S:1100" 
-  fo (unsigned'("1100")) returns "U:1100" 
-  fo (TRUE)              returns "L:T"
-  fo (127)               returns "I:127"
-The internal behavior of fo is irrelevant to the typical user. -
  -
The fo function is currently overloaded as follows:
- -
  function fo (Arg: unsigned)          return string;
-  function fo (Arg: signed)            return string;
-  function fo (Arg: std_logic_vector)  return string;
-  function fo (Arg: std_ulogic_vector) return string;
-  function fo (Arg: bit_vector)        return string;
-  function fo (Arg: integer)           return string;
-  function fo (Arg: std_ulogic)        return string;
-  function fo (Arg: bit)               return string;
-  function fo (Arg: boolean)           return string; 
-  function fo (Arg: character)         return string;
-  function fo (Arg: string)            return string;
-  function fo (Arg: time)              return string;
- -


To support null-terminated strings, the function fo(Arg: -string) processes Arg up to the first NUL character, -if any. If you want the whole string to be outputted you can just enter -the string as a direct argument in fprint.  See also the -examples in the testbench. -

-
- -

-Format specifiers

-The general format of a format specifier is: -
   %[-][n]c
-The optional - sign specifies left justified output; default is -right justified. -

The optional number n specifies a field-width. If it is not specified, -fprint -does something reasonable. -

c is the conversion specifier. Currently the following conversion -specifiers are supported: -

-
-r
- -
-reasonable output format (inspired by Synopsys VSS)
- -
Prints the ``most reasonable'' representation e.g. hex for -unsigned, signed and other bit-like vectors (not preferred for integers)
- -
-b
- -
-bit-oriented output
- -
-d
- -
-decimal output
- -
-s
- -
-string output (e.g. in combination with 'IMAGE for enum types)
- -
-q
- -
-``qualified'' string output (shows internal representation from fo)
- -
-{}
- -
-Iteration operator, used as follows:
- -
-%n{<format-string>}
- -
In this case, n is the iteration count and is mandatory. Iteration -can be nested.
- -
-

-Special characters

-To print a double quote,  use '""' in the format string (VHDL -convention). To print the special characters, '\', and '%', -escape them with '\'. To prevent '{' and '}' -from being interpreted as opening and closing brackets in iteration strings, -escape them with '\'. -

A newline is specified in the format string by '\n'. -

-


-

-Things to notice

-The fprint function expands into VHDL write and writeline -commands. As in plain VHDL, nothing will be written to the output file -until a writeline is given. Therefore, don't forget to include -'\n' -commands in the format string, or it ``will not work''. -

The preferred format specifier for integers is, naturally, %d. -This calls the VHDL write for integers. If you specify a field -width that is too small, the field will automatically be expanded. If you -use %r for integers, the field is not expanded automatically, which -means that some digits are simply thrown away. This may sometimes be useful -but it is also dangerous. Look at the test bench output for differences -between %d and %r output. -

When using the %d format specifier, the VHDL constraints for -the allowed integer range apply. -

In VHDL, signed/unsigned types have been standardized only relatively -recently, in the package IEEE.numeric_std. The lack of a standard -has caused (and is causing) portability issues. The most popular non-standard -package that defines signed/unsigned is IEEE.std_logic_arith from -Synopsys. PCK_FIO works with both packages,  but refers to the standard -package IEEE.numeric_std by default. To use IEEE.std_logic_arith -instead, replace the reference to IEEE.numeric_std in the source -code.  This needs to be done consistently in a design database (e.g. -in the PCK_FIO test bench as well). -

-


-

-Methodology notes

-The obvious application for fprint is in test benches, to produce -output files that trace the simulation behavior. -

Another interesting application for fprint is to produce info, -warning and error messages in your models. As it can take arguments, fprint -is much better suited for this task than VHDL's assert or report -statements. Actually fprint produces its own (few) warning messages. -

An advanced usage is the generation of test vectors in a specific format. -Instead of using the fo functions, you can write your own set -of functions that return the symbols of a specific test format in a way -that is understandable to the fprint format specifiers. As an -example, when a high output value should be represented using the symbol -'H' it suffices to write a conversion function that returns "B:H" and call -it in combination with the %b format specifier. -

-


-

-Parametrization

-Prefix and postfix strings for bit-oriented and hex-oriented output are -parameterizable in the packages to accommodate different output styles. -The settings in the distribution are such that hex output is indicated -by the prefix '0x', while  bit output prefix and postfix are empty -strings. -

You can adapt the output style by modifying the following constants -in the package header: -

   -- prefix string for hex output -
  -- VHDL style:    "X""" -
  -- Verilog style: "h'" -
  -- C style:       "0x" -
  constant FIO_h_PRE:  string := "0x"; -

  -- postfix string for hex output -
  -- VHDL style:    """" -
  constant FIO_h_POST: string := ""; -

  -- prefix string for bit vector output -
  -- VHDL style:    "B""" -
  -- Verilog style: "b'" -
  constant FIO_bv_PRE:  string := ""; -

  -- postfix string for bit vector output -
  -- VHDL style:    """" -
  constant FIO_bv_POST: string := ""; -

  -- prefix string for bit output -
  -- VHDL style:    "'" -
  -- Verilog style: "b'" -
  constant FIO_b_PRE:  string := ""; -

  -- postfix string for bit output -
  -- VHDL style:    "'" -
  constant FIO_b_POST: string := ""; -

-


-

-Test bench

-Included in the distribution are the files TB_PCK_FIO_1987.vhd and -TB_PCK_FIO_1993 with a test bench,depending on the standard you're -running, for the PCK_FIO package. The file PCK_FIO.out.gold contains -the expected output. If you run the test bench it should produce the file -PCK_FIO.out -that should be identical to PCK_FIO.out.gold. The source files -should be analyzed in a VHDL library EASICS_PACKAGES. -

A good way to understand fprint is to inspect the test bench -and what it produces. -

-


-

-Known limitations and problems

-This VHDL package is an implementation of a flexible concept. It is likely -to be extended and modified in the future. Backward compatibility is not -guaranteed. Therefore, it is not recommended to give this package the status -of a company wide standard package (or even worse, a VHDL standard package). -Rather, it should be linked with a particular project (and it can be regarded -as a standard package within that project). -

PCK_FIO is available in either standard VHDL Std1076-1987 or standard -VHDL Std1076-1993. Nevertheless, some simulators/versions have problems -with the package. The following is an overview of currently known issues: -
  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PCK_FIO_1987 and various simulators/versions
SimulatorPCK_FIO_1987
Synopsys VSS 3.5 and earlierIncorrect (all zero) output in compiled mode
Synopsys VSS 97.01OK
Synopsys VSS/Scirocco 2000.02Incorrect output in compiled mode, interpreted mode works
Mentor quickhdlOK
Modeltech modelsimOK
Cadence LeapfrogShould work with 4.4.1 -
Mysterious problems have been reported - please run the test bench -and report problems
- -
  -
- - - - - - - - - - - - - - - - - - - - - - - - - -
PCK_FIO_1993 and various simulators/versions
SimulatorPCK_FIO_1993
Synopsys VSS/Scirocco 2000.02Compile errors due to improper handling of files by Synopsys
Synopsys VSS/Scirocco 2000.06works fine
Modeltech modelsim 5.4c and higherOK
- -

Although the package name suggests file IO, it only does file output. -

-


-

-Author

-Jan Decaluwe -

-


- - + + + + + + VHDL package for formatted file output + + + + +
+

+Name

+PCK_FIO - VHDL package for  formatted file output +

+


+

+Contents

+Usage +
The file output function 'fo' +
Format specifiers +
Special characters +
Things to watch out for +
Methodology notes +
Parametrization +
Test bench +
Known limitations and problems +
Author +

+


+

+Usage

+PCK_FIO is a VHDL package that defines  fprint, a function +for formatted file output. +

After installing the package you can call fprint as follows: +

  fprint(F, L, Format, fo(Expr_1), fo(Expr_2), ... fo(Expr_n));
+where F is the filehandle and L is the line variable. +

The argument Format is the format string, which consists of ``normal'' +substrings which are copied verbatim, and format specifiers, starting with +'%'. +A typical format string looks as follows: +

   "Arg1 = %6r, Arg2 = %10d, Arg3 = %-5r\n"
+The remaining arguments are the expressions whose results you want to write +to the file, embedded in fo function calls. There can be 0 to +32 of such arguments. The expressions can be of any type for which an fo +function exists. String expressions can also be called directly. +

+


+

+The file output function 'fo'

+The fo (file output) functions do the trick. They +return a tagged string representation that is meaningful to format specifiers. +Here are some examples: +
  fo (signed'("1100"))   returns "S:1100" 
+  fo (unsigned'("1100")) returns "U:1100" 
+  fo (TRUE)              returns "L:T"
+  fo (127)               returns "I:127"
+The internal behavior of fo is irrelevant to the typical user. +
  +
The fo function is currently overloaded as follows:
+ +
  function fo (Arg: unsigned)          return string;
+  function fo (Arg: signed)            return string;
+  function fo (Arg: std_logic_vector)  return string;
+  function fo (Arg: std_ulogic_vector) return string;
+  function fo (Arg: bit_vector)        return string;
+  function fo (Arg: integer)           return string;
+  function fo (Arg: std_ulogic)        return string;
+  function fo (Arg: bit)               return string;
+  function fo (Arg: boolean)           return string; 
+  function fo (Arg: character)         return string;
+  function fo (Arg: string)            return string;
+  function fo (Arg: time)              return string;
+ +


To support null-terminated strings, the function fo(Arg: +string) processes Arg up to the first NUL character, +if any. If you want the whole string to be outputted you can just enter +the string as a direct argument in fprint.  See also the +examples in the testbench. +

+
+ +

+Format specifiers

+The general format of a format specifier is: +
   %[-][n]c
+The optional - sign specifies left justified output; default is +right justified. +

The optional number n specifies a field-width. If it is not specified, +fprint +does something reasonable. +

c is the conversion specifier. Currently the following conversion +specifiers are supported: +

+
+r
+ +
+reasonable output format (inspired by Synopsys VSS)
+ +
Prints the ``most reasonable'' representation e.g. hex for +unsigned, signed and other bit-like vectors (not preferred for integers)
+ +
+b
+ +
+bit-oriented output
+ +
+d
+ +
+decimal output
+ +
+s
+ +
+string output (e.g. in combination with 'IMAGE for enum types)
+ +
+q
+ +
+``qualified'' string output (shows internal representation from fo)
+ +
+{}
+ +
+Iteration operator, used as follows:
+ +
+%n{<format-string>}
+ +
In this case, n is the iteration count and is mandatory. Iteration +can be nested.
+ +
+

+Special characters

+To print a double quote,  use '""' in the format string (VHDL +convention). To print the special characters, '\', and '%', +escape them with '\'. To prevent '{' and '}' +from being interpreted as opening and closing brackets in iteration strings, +escape them with '\'. +

A newline is specified in the format string by '\n'. +

+


+

+Things to notice

+The fprint function expands into VHDL write and writeline +commands. As in plain VHDL, nothing will be written to the output file +until a writeline is given. Therefore, don't forget to include +'\n' +commands in the format string, or it ``will not work''. +

The preferred format specifier for integers is, naturally, %d. +This calls the VHDL write for integers. If you specify a field +width that is too small, the field will automatically be expanded. If you +use %r for integers, the field is not expanded automatically, which +means that some digits are simply thrown away. This may sometimes be useful +but it is also dangerous. Look at the test bench output for differences +between %d and %r output. +

When using the %d format specifier, the VHDL constraints for +the allowed integer range apply. +

In VHDL, signed/unsigned types have been standardized only relatively +recently, in the package IEEE.numeric_std. The lack of a standard +has caused (and is causing) portability issues. The most popular non-standard +package that defines signed/unsigned is IEEE.std_logic_arith from +Synopsys. PCK_FIO works with both packages,  but refers to the standard +package IEEE.numeric_std by default. To use IEEE.std_logic_arith +instead, replace the reference to IEEE.numeric_std in the source +code.  This needs to be done consistently in a design database (e.g. +in the PCK_FIO test bench as well). +

+


+

+Methodology notes

+The obvious application for fprint is in test benches, to produce +output files that trace the simulation behavior. +

Another interesting application for fprint is to produce info, +warning and error messages in your models. As it can take arguments, fprint +is much better suited for this task than VHDL's assert or report +statements. Actually fprint produces its own (few) warning messages. +

An advanced usage is the generation of test vectors in a specific format. +Instead of using the fo functions, you can write your own set +of functions that return the symbols of a specific test format in a way +that is understandable to the fprint format specifiers. As an +example, when a high output value should be represented using the symbol +'H' it suffices to write a conversion function that returns "B:H" and call +it in combination with the %b format specifier. +

+


+

+Parametrization

+Prefix and postfix strings for bit-oriented and hex-oriented output are +parameterizable in the packages to accommodate different output styles. +The settings in the distribution are such that hex output is indicated +by the prefix '0x', while  bit output prefix and postfix are empty +strings. +

You can adapt the output style by modifying the following constants +in the package header: +

   -- prefix string for hex output +
  -- VHDL style:    "X""" +
  -- Verilog style: "h'" +
  -- C style:       "0x" +
  constant FIO_h_PRE:  string := "0x"; +

  -- postfix string for hex output +
  -- VHDL style:    """" +
  constant FIO_h_POST: string := ""; +

  -- prefix string for bit vector output +
  -- VHDL style:    "B""" +
  -- Verilog style: "b'" +
  constant FIO_bv_PRE:  string := ""; +

  -- postfix string for bit vector output +
  -- VHDL style:    """" +
  constant FIO_bv_POST: string := ""; +

  -- prefix string for bit output +
  -- VHDL style:    "'" +
  -- Verilog style: "b'" +
  constant FIO_b_PRE:  string := ""; +

  -- postfix string for bit output +
  -- VHDL style:    "'" +
  constant FIO_b_POST: string := ""; +

+


+

+Test bench

+Included in the distribution are the files TB_PCK_FIO_1987.vhd and +TB_PCK_FIO_1993 with a test bench,depending on the standard you're +running, for the PCK_FIO package. The file PCK_FIO.out.gold contains +the expected output. If you run the test bench it should produce the file +PCK_FIO.out +that should be identical to PCK_FIO.out.gold. The source files +should be analyzed in a VHDL library EASICS_PACKAGES. +

A good way to understand fprint is to inspect the test bench +and what it produces. +

+


+

+Known limitations and problems

+This VHDL package is an implementation of a flexible concept. It is likely +to be extended and modified in the future. Backward compatibility is not +guaranteed. Therefore, it is not recommended to give this package the status +of a company wide standard package (or even worse, a VHDL standard package). +Rather, it should be linked with a particular project (and it can be regarded +as a standard package within that project). +

PCK_FIO is available in either standard VHDL Std1076-1987 or standard +VHDL Std1076-1993. Nevertheless, some simulators/versions have problems +with the package. The following is an overview of currently known issues: +
  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PCK_FIO_1987 and various simulators/versions
SimulatorPCK_FIO_1987
Synopsys VSS 3.5 and earlierIncorrect (all zero) output in compiled mode
Synopsys VSS 97.01OK
Synopsys VSS/Scirocco 2000.02Incorrect output in compiled mode, interpreted mode works
Mentor quickhdlOK
Modeltech modelsimOK
Cadence LeapfrogShould work with 4.4.1 +
Mysterious problems have been reported - please run the test bench +and report problems
+ +
  +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
PCK_FIO_1993 and various simulators/versions
SimulatorPCK_FIO_1993
Synopsys VSS/Scirocco 2000.02Compile errors due to improper handling of files by Synopsys
Synopsys VSS/Scirocco 2000.06works fine
Modeltech modelsim 5.4c and higherOK
+ +

Although the package name suggests file IO, it only does file output. +

+


+

+Author

+Jan Decaluwe +

+


+ + diff --git a/lib/PCK_FIO-2002.7/PCK_FIO_1987.vhd b/lib/PCK_FIO-2002.7/PCK_FIO_1987.vhd index d4cf8e6..1a1f266 100644 --- a/lib/PCK_FIO-2002.7/PCK_FIO_1987.vhd +++ b/lib/PCK_FIO-2002.7/PCK_FIO_1987.vhd @@ -1,105 +1,105 @@ ----- $Id: PCK_FIO_1987.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - -use STD.TEXTIO.all; - -library IEEE; -use IEEE.std_logic_1164.all; --- signed/unsigned definition: use either std_logic_arith or numeric_std --- use IEEE.std_logic_arith.all; -- the Synopsys one -use IEEE.numeric_std.all; - -package PCK_FIO is - - -- prefix string for hex output - -- VHDL style: "X""" - -- Verilog style: "h'" - -- C style: "0x" - constant FIO_h_PRE: string := "0x"; - - -- postfix string for hex output - -- VHDL style: """" - constant FIO_h_POST: string := ""; - - -- prefix string for bit vector output - -- VHDL style: "B""" - -- Verilog style: "b'" - constant FIO_bv_PRE: string := ""; - - -- postfix string for bit vector output - -- VHDL style: """" - constant FIO_bv_POST: string := ""; - - -- prefix string for bit output - -- VHDL style: "'" - -- Verilog style: "b'" - constant FIO_b_PRE: string := ""; - - -- postfix string for bit output - -- VHDL style: "'" - constant FIO_b_POST: string := ""; - - -- digit width for the string representation of integers - constant FIO_d_WIDTH: integer := 10; - - -- bit width for the string representation of integers - constant FIO_b_WIDTH: integer := 32; - - -- definition of the NIL string (default value for fprint arguments) - -- fprint stops consuming arguments at the first NIL argument - constant FIO_NIL: string := "\"; - - - procedure fprint - (F: out text; - L: inout line; - Format: in string; - A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; - A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; - A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; - A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL - ); - - function fo (Arg: unsigned) return string; - function fo (Arg: signed) return string; - function fo (Arg: std_logic_vector) return string; - function fo (Arg: std_ulogic_vector) return string; - function fo (Arg: bit_vector) return string; - function fo (Arg: integer) return string; - function fo (Arg: std_ulogic) return string; - function fo (Arg: bit) return string; - function fo (Arg: boolean) return string; - function fo (Arg: character) return string; - function fo (Arg: string) return string; - function fo (Arg: time) return string; - - procedure FIO_FormatExpand (FMT: inout line; - Format: in string; - StartPointer: in positive); - -end PCK_FIO; - +---- $Id: PCK_FIO_1987.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + +use STD.TEXTIO.all; + +library IEEE; +use IEEE.std_logic_1164.all; +-- signed/unsigned definition: use either std_logic_arith or numeric_std +-- use IEEE.std_logic_arith.all; -- the Synopsys one +use IEEE.numeric_std.all; + +package PCK_FIO is + + -- prefix string for hex output + -- VHDL style: "X""" + -- Verilog style: "h'" + -- C style: "0x" + constant FIO_h_PRE: string := "0x"; + + -- postfix string for hex output + -- VHDL style: """" + constant FIO_h_POST: string := ""; + + -- prefix string for bit vector output + -- VHDL style: "B""" + -- Verilog style: "b'" + constant FIO_bv_PRE: string := ""; + + -- postfix string for bit vector output + -- VHDL style: """" + constant FIO_bv_POST: string := ""; + + -- prefix string for bit output + -- VHDL style: "'" + -- Verilog style: "b'" + constant FIO_b_PRE: string := ""; + + -- postfix string for bit output + -- VHDL style: "'" + constant FIO_b_POST: string := ""; + + -- digit width for the string representation of integers + constant FIO_d_WIDTH: integer := 10; + + -- bit width for the string representation of integers + constant FIO_b_WIDTH: integer := 32; + + -- definition of the NIL string (default value for fprint arguments) + -- fprint stops consuming arguments at the first NIL argument + constant FIO_NIL: string := "\"; + + + procedure fprint + (F: out text; + L: inout line; + Format: in string; + A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; + A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; + A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; + A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL + ); + + function fo (Arg: unsigned) return string; + function fo (Arg: signed) return string; + function fo (Arg: std_logic_vector) return string; + function fo (Arg: std_ulogic_vector) return string; + function fo (Arg: bit_vector) return string; + function fo (Arg: integer) return string; + function fo (Arg: std_ulogic) return string; + function fo (Arg: bit) return string; + function fo (Arg: boolean) return string; + function fo (Arg: character) return string; + function fo (Arg: string) return string; + function fo (Arg: time) return string; + + procedure FIO_FormatExpand (FMT: inout line; + Format: in string; + StartPointer: in positive); + +end PCK_FIO; + diff --git a/lib/PCK_FIO-2002.7/PCK_FIO_1987_BODY.vhd b/lib/PCK_FIO-2002.7/PCK_FIO_1987_BODY.vhd index 44e42cf..a5f9927 100644 --- a/lib/PCK_FIO-2002.7/PCK_FIO_1987_BODY.vhd +++ b/lib/PCK_FIO-2002.7/PCK_FIO_1987_BODY.vhd @@ -1,821 +1,821 @@ ----- $Id: PCK_FIO_1987_BODY.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - -package body PCK_FIO is - - -------------------------- - -- FIO Warnings support -- - -------------------------- - - procedure FIO_Warning_Fsbla (F: out text; - L: inout line; - Format: in string; - Pointer: in positive) is - begin - fprint (F, L, "\n** Warning: FIO_PrintLastValue: " & - "Format specifier beyond last argument\n"); - fprint (F, L, "** in format string: ""%s""\n", Format); - fprint (F, L, "** "); - for i in 1 to Pointer-1 loop - fprint (F, L, "-"); - end loop; - fprint (F, L, "^\n"); - end FIO_Warning_Fsbla; - - procedure FIO_Warning_Ufs (F: out text; - L: inout line; - Format: in string; - Pointer: in positive; - Char: in character) is - begin - fprint (F, L, "\n** Warning: FIO_PrintArg: " & - "Unexpected format specifier '%r'\n", - fo(Char)); - fprint (F, L, "** in format string: ""%s""\n", Format) ; - fprint (F, L, "** "); - for i in 1 to Pointer-1 loop - fprint (F, L, "-"); - end loop; - fprint (F, L, "^\n** Assuming 'q' to proceed: "); - end FIO_Warning_Ufs; - - - ---------------------------------- - -- bit conversion support -- - ---------------------------------- - - type T_bit_map is array(bit) of character; - - constant C_BIT_MAP: T_bit_map - := ('0', '1'); - - ---------------------------------- - -- std_logic conversion support -- - ---------------------------------- - - type T_std_logic_map is array(std_ulogic) of character; - - constant C_STD_LOGIC_MAP: T_std_logic_map - := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); - - ------------------------------ - -- Digit conversion support -- - ------------------------------ - - -- types & constants - - subtype S_digit_chars is character range '0' to '9'; - subtype S_digits is integer range 0 to 9 ; - - type T_digit_chars_map is array(S_digit_chars) of S_digits; - - constant C_DIGIT_CHARS_MAP: T_digit_chars_map - := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - - type T_digits_map is array(S_digits) of S_digit_chars; - - constant C_DIGITS_MAP: T_digits_map - := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); - - - -------------------------------- - -- Decimal conversion support -- - -------------------------------- - - -- unsigned to decimal - - function U_To_d (Arg: string) return integer is - constant Argument: string(Arg'length downto 1) := Arg; - variable Result: integer := 0; - begin - for i in Argument'range loop - case Argument(i) is when '1' => Result := 2**(i-1) + Result; - when '0' => null; - when others => return(-1); - end case; - end loop; - return (Result); - end U_To_d; - - -- signed to decimal - - function S_To_d (Arg: string) return integer is - constant Argument: string(Arg'length downto 1) := Arg; - variable Result: integer := 0; - begin - case Argument(Argument'left) is - when '1' => Result := - 2**(Argument'left-1); - when '0' => Result := 0; - when others => return (integer'low); - end case; - for i in Argument'left-1 downto 1 loop - case Argument(i) is when '1' => Result := 2**(i-1) + Result; - when '0' => null; - when others => return(integer'low); - end case; - end loop; - return (Result); - end S_To_d; - - -- string to decimal - - function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is - constant Sign: character := Arg(1); - constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length); - variable Char: character; - variable Result: integer := 0; - begin - Result := 0; - for i in Value'range loop - Result := Result * 10; - Char := Value(i); - if (Char /= ' ') then - Result := Result + C_DIGIT_CHARS_MAP(Char); - end if; - end loop; - case Sign is when '-' => return(-Result); - when others => return(Result); - end case; - end I_To_d; - - -- boolean (0,1) to decimal - - function B_To_d (Arg: string(1 to 1)) return integer is - begin - case Arg is when "1" => return(1); - when "0" => return(0); - when others => return(-1); - end case; - end B_To_d; - - -- boolean (T,F) to decimal - - function L_To_d (Arg: string(1 to 1)) return integer is - begin - case Arg is when "T" => return(1); - when others => return(0); - end case; - end L_To_d; - - - - ---------------------------- - -- Hex conversion support -- - ---------------------------- - - -- Constants & types - - constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?"; - - -- Function to return Hex index of a nibble - - function U_To_h_Index(Arg: string(4 downto 1)) return integer is - variable Index: integer := 0; - begin - for i in Arg'range loop - case Arg(i) is when '1' => Index := 2**(i-1) + Index; - when '0' => null; - when others => return (17); - end case; - end loop; - return (Index+1); - end U_To_h_Index; - - -- Hex conversion - - function U_To_h (Arg: string) return string is - variable Result: string((Arg'length-1)/4 +1 downto 1); - variable ExtArg: string(Result'length*4 downto 1) := (others => '0'); - begin - ExtArg(Arg'length downto 1) := Arg; - for i in Result'range loop - Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) )); - end loop; - return (FIO_h_PRE & Result & FIO_h_POST); - end U_To_h; - - - - ---------------------------- - -- Bit conversion support -- - ---------------------------- - - function L_To_b (Arg: string(1 to 1)) return string is - variable Result: string(1 to 1); - begin - case Arg is when "T" => Result := "1"; - when others => Result := "0"; - end case; - return(FIO_b_PRE & Result & FIO_b_POST); - end L_To_b; - - - function I_To_b (Arg: string(1 to FIO_d_WIDTH+1); - Justified: side; - Width: integer) return string is - - variable IntValue: integer := I_To_d(Arg); - variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' '); - variable Sign: character := ' '; - constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' '); - variable BitWidth: integer range 0 to FIO_b_WIDTH; - variable MsPos: integer range 1 to BitValue'length; - variable BitValueExtended: string(1 to 2*FIO_b_WIDTH); - - begin - - if (IntValue < 0) then - Sign := '-'; - IntValue := -IntValue; - end if; - - for i in BitValue'reverse_range loop - BitValue(i) := C_DIGITS_MAP(IntValue mod 2); - IntValue := IntValue / 2; - exit when (IntValue = 0); - end loop; - - BitValueExtended := BitValue & Blanks; - - if (Width = 0) or (Width > FIO_b_WIDTH+1) then - BitWidth := FIO_b_WIDTH; - else - BitWidth := Width-1; - end if; - - if (Justified = RIGHT) then - return (FIO_bv_PRE & - Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) & - FIO_bv_POST); - else - for i in BitValue'range loop - if BitValue(i) /= ' ' then - MSPos := i; - exit; - end if; - end loop; - return (FIO_bv_PRE & - Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) & - FIO_bv_POST); - end if; - - end I_To_b; - - - ----------------------------------- - -- Reasonable conversion support -- - ----------------------------------- - - function I_To_r (Arg: string(1 to FIO_d_WIDTH+1); - Justified: side; - Width: integer) return string is - constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1); - constant Sign: character := Arg(1); - constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' '); - variable IntWidth: integer range 0 to FIO_d_WIDTH; - variable MsPos: integer range 1 to Value'length; - variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks; - begin - if (Width = 0) or (Width > FIO_d_WIDTH+1) then - IntWidth := FIO_d_WIDTH; - else - IntWidth := Width-1; - end if; - if (Justified = RIGHT) then - return (Sign & Value(Value'length-IntWidth+1 to Value'length)); - else - for i in Value'range loop - if Value(i) /= ' ' then - MSPos := i; - exit; - end if; - end loop; - return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1)); - end if; - end I_To_r; - - - ------------------------------------------- - -- Reasonable output conversion function -- - ------------------------------------------- - - function ReasonableOutput (Arg: string; - Justified: side; - Width: integer) return string is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:" | "S:" | "V:" => - return U_To_h(Value); - when "I:" => - return I_To_r(Value, Justified, Width); - when "B:" | "L:" | "C:" => - return Value; - when others => - return Argument; - end case; - - end ReasonableOutput; - - - ------------------------------------ - -- Bit output conversion function -- - ------------------------------------ - - function BitOutput (Arg: string; - Justified: side; - Width: integer) return string is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:" | "S:" | "V:" => - return (FIO_bv_PRE & Value & FIO_bv_POST); - when "B:" => - -- Value(1 to 1) instead of Value for LeapFrog - return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST); - when "I:" => - return I_To_b(Value, Justified, Width); - when "L:" => - -- Value(1 to 1) instead of Value for LeapFrog - return L_To_b(Value(1 to 1)); - when others => - return Argument; - end case; - - end BitOutput; - - - ------------------------------------------- - -- Decimal output conversion function -- - ------------------------------------------- - - function DecimalOutput (Arg: string) return integer is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:"| "V:" => - return U_To_d(Value); - when "S:" => - return S_To_d(Value); - when "I:" => - return I_To_d(Value); - when "B:" => - return B_To_d(Value); - when "L:" => - return L_To_d(Value); - when others => - return integer'low; - end case; - - end DecimalOutput; - - - ---------------------------- - -- Atomic print functions -- - ---------------------------- - - -- test for end of format string - - function FIO_EOS (Format: in string; - Pointer: in integer) - return boolean is - begin - return (Pointer > Format'length); - end FIO_EOS; - - - -- Atomic value print function - - procedure FIO_PrintValue (F: out text; - L: inout line; - Format: in string; - Pointer: inout integer; - Last: in boolean := FALSE) is - variable Char: character; - begin - while (not FIO_EOS(Format, Pointer)) loop - Char := Format(Pointer); - case Char is - when '\' => - Pointer := Pointer + 1; - exit when (FIO_EOS(Format, Pointer)); - Char := Format(Pointer); - case Char is when 'n' => writeline(F, L); - when others => write(L, Char); - end case; - when '%' => - if Last then - FIO_Warning_Fsbla(F, L, Format, Pointer); - end if; - Pointer := Pointer + 1; - exit; - when others => - write(L, char); - end case; - Pointer := Pointer + 1; - end loop; - end FIO_PrintValue; - - - ---- Atomic argument print function - - procedure FIO_PrintArg (F: out text; - L: inout line; - Format: in string; - Pointer: inout integer; - Arg: in string) is - variable Char: character; - variable Justified: side; - variable Width: integer; - begin - - FIO_PrintValue(F, L, Format, Pointer); - - Justified := RIGHT; - Width := 0; - while (not FIO_EOS(Format, Pointer)) loop - Char := Format(Pointer); - case Char is - when '-' => - Justified := LEFT; - Pointer := Pointer + 1; - when '0' to '9' => - Width := Width*10 + C_DIGIT_CHARS_MAP(Char); - Pointer := Pointer + 1; - when 'r' => - write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'b' => - write(L, BitOutput(Arg, Justified, Width), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'd' => - write(L, DecimalOutput(Arg), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'q' | 's' => - write(L, Arg, Justified, Width); - Pointer := Pointer + 1; - exit; - when others => - FIO_Warning_Ufs(F, L, Format, Pointer, Char); - write(L, Arg, Justified, Width); - Pointer := Pointer + 1; - exit; - end case; - end loop; - end FIO_PrintArg; - - - ----------------------------------------------------- - -- The format string iteration expansion procedure -- - ----------------------------------------------------- - - procedure FIO_FormatExpand (FMT: inout line; - Format: in string; - StartPointer: in positive) is - - variable Pointer: positive := StartPointer; - variable TokenStart: positive; - variable IterStringStart: positive; - variable IterStringEnd: positive; - variable IterCount: natural; - variable OpenBrackets: natural; - variable L: line; - - begin - - FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - - -- look for format specifier - when '%' => - - -- initialize iteration token search - TokenStart := Pointer; - IterCount := 0; - Pointer := Pointer + 1; - - -- start iteration token search - TOKEN_READ: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - - -- read iteration counter - when '0' to '9' => - IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer)); - Pointer := Pointer + 1; - - -- expect open bracket - when '{' => - - -- initialize iteration string read - OpenBrackets := 1; - IterStringStart := Pointer + 1; - Pointer := Pointer + 1; - -- quit prematurely when iteration count is 0 - next FORMAT_SEARCH when (IterCount = 0); - - -- start iteration string read - ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - -- keep track of open brackets - when '{' => - OpenBrackets := OpenBrackets + 1; - Pointer := Pointer + 1; - -- when closing bracket is found, process iteration string - when '}' => - OpenBrackets := OpenBrackets - 1; - if (OpenBrackets = 0) then - IterStringEnd := Pointer-1; - if (TokenStart /= 1) then - write(L, Format(1 to TokenStart-1)); - end if; - for i in 1 to IterCount loop - write(L, Format(IterStringStart to IterStringEnd)); - end loop; - if (IterStringEnd /= Format'length) then - write(L, Format(IterStringEnd+2 to Format'length)); - end if; - -- call expansion procedure recursively on expanded format - FIO_FormatExpand(FMT, L.all, TokenStart); - deallocate(L); - return; - end if; - Pointer := Pointer + 1; - -- skip escaped characters - when '\' => - Pointer := Pointer + 2; - -- read iteration string - when others => - Pointer := Pointer + 1; - - end case; - - end loop ITER_STRING_READ; - - -- stop iteration token search when no opening bracket found - when others => - Pointer := Pointer + 1; - next FORMAT_SEARCH; - - end case; - - end loop TOKEN_READ; - - -- skip escaped characters - when '\' => - Pointer := Pointer + 2; - - -- read other characters - when others => - Pointer := Pointer + 1; - - end case; - - end loop FORMAT_SEARCH; - - write(FMT, Format); - deallocate(L); - - end FIO_FormatExpand; - - - - -------------------------- - -- The fprint procedure -- - -------------------------- - - procedure fprint - (F: out text; - L: inout line; - Format: in string; - A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; - A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; - A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; - A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL - ) is - - variable Pointer: integer; - variable FMT: line; - - begin - - Pointer := 1; - - FIO_FormatExpand (FMT, Format, Format'low); - - if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 ); - if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 ); - if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 ); - if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 ); - if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 ); - if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 ); - if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 ); - if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 ); - if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 ); - if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10); - if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11); - if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12); - if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13); - if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14); - if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15); - if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16); - if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17); - if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18); - if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19); - if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20); - if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21); - if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22); - if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23); - if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24); - if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25); - if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26); - if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27); - if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28); - if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29); - if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30); - if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31); - if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32); - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - - FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE); - - deallocate(FMT); - - end fprint; - - - ------------------------------------------- - -- Formatted output conversion functions -- - ------------------------------------------- - - function fo (Arg: unsigned) return string is - constant Argument: unsigned(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("U:" & Result); - end fo; - - function fo (Arg: signed) return string is - constant Argument: signed(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("S:" & Result); - end fo; - - function fo (Arg: std_logic_vector) return string is - constant Argument: std_logic_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: std_ulogic_vector) return string is - constant Argument: std_ulogic_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: bit_vector) return string is - constant Argument: bit_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_BIT_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: integer) return string is - variable Argument: integer := Arg; - variable Result: string(1 to FIO_d_WIDTH) := (others => ' '); - variable Sign: character := ' '; - begin - if (Argument < 0) and (Argument /= integer'low) then - Sign := '-'; - Argument := -Argument; - end if; - for i in Result'reverse_range loop - Result(i) := C_DIGITS_MAP(Argument mod 10); - Argument := Argument / 10; - exit when (Argument = 0); - end loop; - return ("I:" & Sign & Result); - end fo; - - function fo (Arg: std_ulogic) return string is - begin - return ("B:" & C_STD_LOGIC_MAP(Arg)); - end fo; - - function fo (Arg: bit) return string is - begin - return ("B:" & C_BIT_MAP(Arg)); - end fo; - - function fo (Arg: boolean) return string is - begin - if (ARG = TRUE) then - return ("L:T"); - else - return ("L:F"); - end if; - end fo; - - function fo (Arg: character) return string is - begin - return ("C:" & Arg); - end fo; - - -- auxilary function fgets(Arg: string) - -- gives index until first NUL - -- reads string from 1 to Arg'length - function fgets (Arg: string) return integer is - variable index: integer := Arg'length; - begin - for i in 1 to Arg'length loop - if Arg(i) = NUL then - index := i - 1; - exit; - else - null; - end if; - end loop; - return index; - end fgets; - - function fo (Arg: string) return string is - begin - return Arg(1 to fgets(Arg)); - end fo; - - function fo (Arg: time) return string is - begin - return fo (integer (Arg / 1 ns)); - end fo; - -end PCK_FIO; - - - - - - - - - - - - - +---- $Id: PCK_FIO_1987_BODY.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + +package body PCK_FIO is + + -------------------------- + -- FIO Warnings support -- + -------------------------- + + procedure FIO_Warning_Fsbla (F: out text; + L: inout line; + Format: in string; + Pointer: in positive) is + begin + fprint (F, L, "\n** Warning: FIO_PrintLastValue: " & + "Format specifier beyond last argument\n"); + fprint (F, L, "** in format string: ""%s""\n", Format); + fprint (F, L, "** "); + for i in 1 to Pointer-1 loop + fprint (F, L, "-"); + end loop; + fprint (F, L, "^\n"); + end FIO_Warning_Fsbla; + + procedure FIO_Warning_Ufs (F: out text; + L: inout line; + Format: in string; + Pointer: in positive; + Char: in character) is + begin + fprint (F, L, "\n** Warning: FIO_PrintArg: " & + "Unexpected format specifier '%r'\n", + fo(Char)); + fprint (F, L, "** in format string: ""%s""\n", Format) ; + fprint (F, L, "** "); + for i in 1 to Pointer-1 loop + fprint (F, L, "-"); + end loop; + fprint (F, L, "^\n** Assuming 'q' to proceed: "); + end FIO_Warning_Ufs; + + + ---------------------------------- + -- bit conversion support -- + ---------------------------------- + + type T_bit_map is array(bit) of character; + + constant C_BIT_MAP: T_bit_map + := ('0', '1'); + + ---------------------------------- + -- std_logic conversion support -- + ---------------------------------- + + type T_std_logic_map is array(std_ulogic) of character; + + constant C_STD_LOGIC_MAP: T_std_logic_map + := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); + + ------------------------------ + -- Digit conversion support -- + ------------------------------ + + -- types & constants + + subtype S_digit_chars is character range '0' to '9'; + subtype S_digits is integer range 0 to 9 ; + + type T_digit_chars_map is array(S_digit_chars) of S_digits; + + constant C_DIGIT_CHARS_MAP: T_digit_chars_map + := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + + type T_digits_map is array(S_digits) of S_digit_chars; + + constant C_DIGITS_MAP: T_digits_map + := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + + -------------------------------- + -- Decimal conversion support -- + -------------------------------- + + -- unsigned to decimal + + function U_To_d (Arg: string) return integer is + constant Argument: string(Arg'length downto 1) := Arg; + variable Result: integer := 0; + begin + for i in Argument'range loop + case Argument(i) is when '1' => Result := 2**(i-1) + Result; + when '0' => null; + when others => return(-1); + end case; + end loop; + return (Result); + end U_To_d; + + -- signed to decimal + + function S_To_d (Arg: string) return integer is + constant Argument: string(Arg'length downto 1) := Arg; + variable Result: integer := 0; + begin + case Argument(Argument'left) is + when '1' => Result := - 2**(Argument'left-1); + when '0' => Result := 0; + when others => return (integer'low); + end case; + for i in Argument'left-1 downto 1 loop + case Argument(i) is when '1' => Result := 2**(i-1) + Result; + when '0' => null; + when others => return(integer'low); + end case; + end loop; + return (Result); + end S_To_d; + + -- string to decimal + + function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is + constant Sign: character := Arg(1); + constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length); + variable Char: character; + variable Result: integer := 0; + begin + Result := 0; + for i in Value'range loop + Result := Result * 10; + Char := Value(i); + if (Char /= ' ') then + Result := Result + C_DIGIT_CHARS_MAP(Char); + end if; + end loop; + case Sign is when '-' => return(-Result); + when others => return(Result); + end case; + end I_To_d; + + -- boolean (0,1) to decimal + + function B_To_d (Arg: string(1 to 1)) return integer is + begin + case Arg is when "1" => return(1); + when "0" => return(0); + when others => return(-1); + end case; + end B_To_d; + + -- boolean (T,F) to decimal + + function L_To_d (Arg: string(1 to 1)) return integer is + begin + case Arg is when "T" => return(1); + when others => return(0); + end case; + end L_To_d; + + + + ---------------------------- + -- Hex conversion support -- + ---------------------------- + + -- Constants & types + + constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?"; + + -- Function to return Hex index of a nibble + + function U_To_h_Index(Arg: string(4 downto 1)) return integer is + variable Index: integer := 0; + begin + for i in Arg'range loop + case Arg(i) is when '1' => Index := 2**(i-1) + Index; + when '0' => null; + when others => return (17); + end case; + end loop; + return (Index+1); + end U_To_h_Index; + + -- Hex conversion + + function U_To_h (Arg: string) return string is + variable Result: string((Arg'length-1)/4 +1 downto 1); + variable ExtArg: string(Result'length*4 downto 1) := (others => '0'); + begin + ExtArg(Arg'length downto 1) := Arg; + for i in Result'range loop + Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) )); + end loop; + return (FIO_h_PRE & Result & FIO_h_POST); + end U_To_h; + + + + ---------------------------- + -- Bit conversion support -- + ---------------------------- + + function L_To_b (Arg: string(1 to 1)) return string is + variable Result: string(1 to 1); + begin + case Arg is when "T" => Result := "1"; + when others => Result := "0"; + end case; + return(FIO_b_PRE & Result & FIO_b_POST); + end L_To_b; + + + function I_To_b (Arg: string(1 to FIO_d_WIDTH+1); + Justified: side; + Width: integer) return string is + + variable IntValue: integer := I_To_d(Arg); + variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' '); + variable Sign: character := ' '; + constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' '); + variable BitWidth: integer range 0 to FIO_b_WIDTH; + variable MsPos: integer range 1 to BitValue'length; + variable BitValueExtended: string(1 to 2*FIO_b_WIDTH); + + begin + + if (IntValue < 0) then + Sign := '-'; + IntValue := -IntValue; + end if; + + for i in BitValue'reverse_range loop + BitValue(i) := C_DIGITS_MAP(IntValue mod 2); + IntValue := IntValue / 2; + exit when (IntValue = 0); + end loop; + + BitValueExtended := BitValue & Blanks; + + if (Width = 0) or (Width > FIO_b_WIDTH+1) then + BitWidth := FIO_b_WIDTH; + else + BitWidth := Width-1; + end if; + + if (Justified = RIGHT) then + return (FIO_bv_PRE & + Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) & + FIO_bv_POST); + else + for i in BitValue'range loop + if BitValue(i) /= ' ' then + MSPos := i; + exit; + end if; + end loop; + return (FIO_bv_PRE & + Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) & + FIO_bv_POST); + end if; + + end I_To_b; + + + ----------------------------------- + -- Reasonable conversion support -- + ----------------------------------- + + function I_To_r (Arg: string(1 to FIO_d_WIDTH+1); + Justified: side; + Width: integer) return string is + constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1); + constant Sign: character := Arg(1); + constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' '); + variable IntWidth: integer range 0 to FIO_d_WIDTH; + variable MsPos: integer range 1 to Value'length; + variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks; + begin + if (Width = 0) or (Width > FIO_d_WIDTH+1) then + IntWidth := FIO_d_WIDTH; + else + IntWidth := Width-1; + end if; + if (Justified = RIGHT) then + return (Sign & Value(Value'length-IntWidth+1 to Value'length)); + else + for i in Value'range loop + if Value(i) /= ' ' then + MSPos := i; + exit; + end if; + end loop; + return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1)); + end if; + end I_To_r; + + + ------------------------------------------- + -- Reasonable output conversion function -- + ------------------------------------------- + + function ReasonableOutput (Arg: string; + Justified: side; + Width: integer) return string is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:" | "S:" | "V:" => + return U_To_h(Value); + when "I:" => + return I_To_r(Value, Justified, Width); + when "B:" | "L:" | "C:" => + return Value; + when others => + return Argument; + end case; + + end ReasonableOutput; + + + ------------------------------------ + -- Bit output conversion function -- + ------------------------------------ + + function BitOutput (Arg: string; + Justified: side; + Width: integer) return string is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:" | "S:" | "V:" => + return (FIO_bv_PRE & Value & FIO_bv_POST); + when "B:" => + -- Value(1 to 1) instead of Value for LeapFrog + return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST); + when "I:" => + return I_To_b(Value, Justified, Width); + when "L:" => + -- Value(1 to 1) instead of Value for LeapFrog + return L_To_b(Value(1 to 1)); + when others => + return Argument; + end case; + + end BitOutput; + + + ------------------------------------------- + -- Decimal output conversion function -- + ------------------------------------------- + + function DecimalOutput (Arg: string) return integer is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:"| "V:" => + return U_To_d(Value); + when "S:" => + return S_To_d(Value); + when "I:" => + return I_To_d(Value); + when "B:" => + return B_To_d(Value); + when "L:" => + return L_To_d(Value); + when others => + return integer'low; + end case; + + end DecimalOutput; + + + ---------------------------- + -- Atomic print functions -- + ---------------------------- + + -- test for end of format string + + function FIO_EOS (Format: in string; + Pointer: in integer) + return boolean is + begin + return (Pointer > Format'length); + end FIO_EOS; + + + -- Atomic value print function + + procedure FIO_PrintValue (F: out text; + L: inout line; + Format: in string; + Pointer: inout integer; + Last: in boolean := FALSE) is + variable Char: character; + begin + while (not FIO_EOS(Format, Pointer)) loop + Char := Format(Pointer); + case Char is + when '\' => + Pointer := Pointer + 1; + exit when (FIO_EOS(Format, Pointer)); + Char := Format(Pointer); + case Char is when 'n' => writeline(F, L); + when others => write(L, Char); + end case; + when '%' => + if Last then + FIO_Warning_Fsbla(F, L, Format, Pointer); + end if; + Pointer := Pointer + 1; + exit; + when others => + write(L, char); + end case; + Pointer := Pointer + 1; + end loop; + end FIO_PrintValue; + + + ---- Atomic argument print function + + procedure FIO_PrintArg (F: out text; + L: inout line; + Format: in string; + Pointer: inout integer; + Arg: in string) is + variable Char: character; + variable Justified: side; + variable Width: integer; + begin + + FIO_PrintValue(F, L, Format, Pointer); + + Justified := RIGHT; + Width := 0; + while (not FIO_EOS(Format, Pointer)) loop + Char := Format(Pointer); + case Char is + when '-' => + Justified := LEFT; + Pointer := Pointer + 1; + when '0' to '9' => + Width := Width*10 + C_DIGIT_CHARS_MAP(Char); + Pointer := Pointer + 1; + when 'r' => + write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'b' => + write(L, BitOutput(Arg, Justified, Width), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'd' => + write(L, DecimalOutput(Arg), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'q' | 's' => + write(L, Arg, Justified, Width); + Pointer := Pointer + 1; + exit; + when others => + FIO_Warning_Ufs(F, L, Format, Pointer, Char); + write(L, Arg, Justified, Width); + Pointer := Pointer + 1; + exit; + end case; + end loop; + end FIO_PrintArg; + + + ----------------------------------------------------- + -- The format string iteration expansion procedure -- + ----------------------------------------------------- + + procedure FIO_FormatExpand (FMT: inout line; + Format: in string; + StartPointer: in positive) is + + variable Pointer: positive := StartPointer; + variable TokenStart: positive; + variable IterStringStart: positive; + variable IterStringEnd: positive; + variable IterCount: natural; + variable OpenBrackets: natural; + variable L: line; + + begin + + FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + + -- look for format specifier + when '%' => + + -- initialize iteration token search + TokenStart := Pointer; + IterCount := 0; + Pointer := Pointer + 1; + + -- start iteration token search + TOKEN_READ: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + + -- read iteration counter + when '0' to '9' => + IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer)); + Pointer := Pointer + 1; + + -- expect open bracket + when '{' => + + -- initialize iteration string read + OpenBrackets := 1; + IterStringStart := Pointer + 1; + Pointer := Pointer + 1; + -- quit prematurely when iteration count is 0 + next FORMAT_SEARCH when (IterCount = 0); + + -- start iteration string read + ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + -- keep track of open brackets + when '{' => + OpenBrackets := OpenBrackets + 1; + Pointer := Pointer + 1; + -- when closing bracket is found, process iteration string + when '}' => + OpenBrackets := OpenBrackets - 1; + if (OpenBrackets = 0) then + IterStringEnd := Pointer-1; + if (TokenStart /= 1) then + write(L, Format(1 to TokenStart-1)); + end if; + for i in 1 to IterCount loop + write(L, Format(IterStringStart to IterStringEnd)); + end loop; + if (IterStringEnd /= Format'length) then + write(L, Format(IterStringEnd+2 to Format'length)); + end if; + -- call expansion procedure recursively on expanded format + FIO_FormatExpand(FMT, L.all, TokenStart); + deallocate(L); + return; + end if; + Pointer := Pointer + 1; + -- skip escaped characters + when '\' => + Pointer := Pointer + 2; + -- read iteration string + when others => + Pointer := Pointer + 1; + + end case; + + end loop ITER_STRING_READ; + + -- stop iteration token search when no opening bracket found + when others => + Pointer := Pointer + 1; + next FORMAT_SEARCH; + + end case; + + end loop TOKEN_READ; + + -- skip escaped characters + when '\' => + Pointer := Pointer + 2; + + -- read other characters + when others => + Pointer := Pointer + 1; + + end case; + + end loop FORMAT_SEARCH; + + write(FMT, Format); + deallocate(L); + + end FIO_FormatExpand; + + + + -------------------------- + -- The fprint procedure -- + -------------------------- + + procedure fprint + (F: out text; + L: inout line; + Format: in string; + A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; + A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; + A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; + A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL + ) is + + variable Pointer: integer; + variable FMT: line; + + begin + + Pointer := 1; + + FIO_FormatExpand (FMT, Format, Format'low); + + if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 ); + if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 ); + if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 ); + if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 ); + if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 ); + if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 ); + if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 ); + if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 ); + if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 ); + if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10); + if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11); + if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12); + if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13); + if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14); + if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15); + if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16); + if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17); + if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18); + if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19); + if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20); + if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21); + if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22); + if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23); + if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24); + if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25); + if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26); + if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27); + if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28); + if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29); + if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30); + if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31); + if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32); + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + + FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE); + + deallocate(FMT); + + end fprint; + + + ------------------------------------------- + -- Formatted output conversion functions -- + ------------------------------------------- + + function fo (Arg: unsigned) return string is + constant Argument: unsigned(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("U:" & Result); + end fo; + + function fo (Arg: signed) return string is + constant Argument: signed(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("S:" & Result); + end fo; + + function fo (Arg: std_logic_vector) return string is + constant Argument: std_logic_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: std_ulogic_vector) return string is + constant Argument: std_ulogic_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: bit_vector) return string is + constant Argument: bit_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_BIT_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: integer) return string is + variable Argument: integer := Arg; + variable Result: string(1 to FIO_d_WIDTH) := (others => ' '); + variable Sign: character := ' '; + begin + if (Argument < 0) and (Argument /= integer'low) then + Sign := '-'; + Argument := -Argument; + end if; + for i in Result'reverse_range loop + Result(i) := C_DIGITS_MAP(Argument mod 10); + Argument := Argument / 10; + exit when (Argument = 0); + end loop; + return ("I:" & Sign & Result); + end fo; + + function fo (Arg: std_ulogic) return string is + begin + return ("B:" & C_STD_LOGIC_MAP(Arg)); + end fo; + + function fo (Arg: bit) return string is + begin + return ("B:" & C_BIT_MAP(Arg)); + end fo; + + function fo (Arg: boolean) return string is + begin + if (ARG = TRUE) then + return ("L:T"); + else + return ("L:F"); + end if; + end fo; + + function fo (Arg: character) return string is + begin + return ("C:" & Arg); + end fo; + + -- auxilary function fgets(Arg: string) + -- gives index until first NUL + -- reads string from 1 to Arg'length + function fgets (Arg: string) return integer is + variable index: integer := Arg'length; + begin + for i in 1 to Arg'length loop + if Arg(i) = NUL then + index := i - 1; + exit; + else + null; + end if; + end loop; + return index; + end fgets; + + function fo (Arg: string) return string is + begin + return Arg(1 to fgets(Arg)); + end fo; + + function fo (Arg: time) return string is + begin + return fo (integer (Arg / 1 ns)); + end fo; + +end PCK_FIO; + + + + + + + + + + + + + diff --git a/lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd b/lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd index 9df893e..937fa04 100644 --- a/lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd +++ b/lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd @@ -1,108 +1,108 @@ ----- $Id: PCK_FIO_1993.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - -use STD.TEXTIO.all; - -library IEEE; -use IEEE.std_logic_1164.all; --- signed/unsigned definition: use either std_logic_arith or numeric_std --- use IEEE.std_logic_arith.all; -- the Synopsys one -use IEEE.numeric_std.all; - -package PCK_FIO is - - - -- prefix string for hex output - -- VHDL style: "X""" - -- Verilog style: "h'" - -- C style: "0x" - constant FIO_h_PRE: string := "0x"; - - -- postfix string for hex output - -- VHDL style: """" - constant FIO_h_POST: string := ""; - - -- prefix string for bit vector output - -- VHDL style: "B""" - -- Verilog style: "b'" - constant FIO_bv_PRE: string := ""; - - -- postfix string for bit vector output - -- VHDL style: """" - constant FIO_bv_POST: string := ""; - - -- prefix string for bit output - -- VHDL style: "'" - -- Verilog style: "b'" - constant FIO_b_PRE: string := ""; - - -- postfix string for bit output - -- VHDL style: "'" - constant FIO_b_POST: string := ""; - - -- digit width for the string representation of integers - constant FIO_d_WIDTH: integer := 10; - - -- bit width for the string representation of integers - constant FIO_b_WIDTH: integer := 32; - - -- definition of the NIL string (default value for fprint arguments) - -- fprint stops consuming arguments at the first NIL argument - constant FIO_NIL: string := "\"; - - procedure fprint - (file F: text; - L: inout line; - Format: in string; - A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; - A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; - A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; - A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL - ); - - function fo (Arg: unsigned) return string; - function fo (Arg: signed) return string; - function fo (Arg: std_logic_vector) return string; - function fo (Arg: std_ulogic_vector) return string; - function fo (Arg: bit_vector) return string; - function fo (Arg: integer) return string; - function fo (Arg: std_ulogic) return string; - function fo (Arg: bit) return string; - function fo (Arg: boolean) return string; - function fo (Arg: character) return string; - function fo (Arg: string) return string; - function fo (Arg: time) return string; - - procedure FIO_FormatExpand (FMT: inout line; - Format: in string; - StartPointer: in positive); - -end PCK_FIO; - - - +---- $Id: PCK_FIO_1993.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + +use STD.TEXTIO.all; + +library IEEE; +use IEEE.std_logic_1164.all; +-- signed/unsigned definition: use either std_logic_arith or numeric_std +-- use IEEE.std_logic_arith.all; -- the Synopsys one +use IEEE.numeric_std.all; + +package PCK_FIO is + + + -- prefix string for hex output + -- VHDL style: "X""" + -- Verilog style: "h'" + -- C style: "0x" + constant FIO_h_PRE: string := "0x"; + + -- postfix string for hex output + -- VHDL style: """" + constant FIO_h_POST: string := ""; + + -- prefix string for bit vector output + -- VHDL style: "B""" + -- Verilog style: "b'" + constant FIO_bv_PRE: string := ""; + + -- postfix string for bit vector output + -- VHDL style: """" + constant FIO_bv_POST: string := ""; + + -- prefix string for bit output + -- VHDL style: "'" + -- Verilog style: "b'" + constant FIO_b_PRE: string := ""; + + -- postfix string for bit output + -- VHDL style: "'" + constant FIO_b_POST: string := ""; + + -- digit width for the string representation of integers + constant FIO_d_WIDTH: integer := 10; + + -- bit width for the string representation of integers + constant FIO_b_WIDTH: integer := 32; + + -- definition of the NIL string (default value for fprint arguments) + -- fprint stops consuming arguments at the first NIL argument + constant FIO_NIL: string := "\"; + + procedure fprint + (file F: text; + L: inout line; + Format: in string; + A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; + A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; + A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; + A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL + ); + + function fo (Arg: unsigned) return string; + function fo (Arg: signed) return string; + function fo (Arg: std_logic_vector) return string; + function fo (Arg: std_ulogic_vector) return string; + function fo (Arg: bit_vector) return string; + function fo (Arg: integer) return string; + function fo (Arg: std_ulogic) return string; + function fo (Arg: bit) return string; + function fo (Arg: boolean) return string; + function fo (Arg: character) return string; + function fo (Arg: string) return string; + function fo (Arg: time) return string; + + procedure FIO_FormatExpand (FMT: inout line; + Format: in string; + StartPointer: in positive); + +end PCK_FIO; + + + diff --git a/lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd b/lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd index 3d123f0..b11e300 100644 --- a/lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd +++ b/lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd @@ -1,814 +1,814 @@ ----- $Id: PCK_FIO_1993_BODY.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - - package body PCK_FIO is - - -------------------------- - -- FIO Warnings support -- - -------------------------- - - procedure FIO_Warning_Fsbla (file F: text; - L: inout line; - Format: in string; - Pointer: in positive) is - begin - fprint (F, L, "\n** Warning: FIO_PrintLastValue: " & - "Format specifier beyond last argument\n"); - fprint (F, L, "** in format string: ""%s""\n", Format); - fprint (F, L, "** "); - for i in 1 to Pointer-1 loop - fprint (F, L, "-"); - end loop; - fprint (F, L, "^\n"); - end FIO_Warning_Fsbla; - - procedure FIO_Warning_Ufs (file F: text; - L: inout line; - Format: in string; - Pointer: in positive; - Char: in character) is - begin - fprint (F, L, "\n** Warning: FIO_PrintArg: " & - "Unexpected format specifier '%r'\n", - fo(Char)); - fprint (F, L, "** in format string: ""%s""\n", Format) ; - fprint (F, L, "** "); - for i in 1 to Pointer-1 loop - fprint (F, L, "-"); - end loop; - fprint (F, L, "^\n** Assuming 'q' to proceed: "); - end FIO_Warning_Ufs; - - - ---------------------------------- - -- bit conversion support -- - ---------------------------------- - - type T_bit_map is array(bit) of character; - - constant C_BIT_MAP: T_bit_map - := ('0', '1'); - - ---------------------------------- - -- std_logic conversion support -- - ---------------------------------- - - type T_std_logic_map is array(std_ulogic) of character; - - constant C_STD_LOGIC_MAP: T_std_logic_map - := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); - - ------------------------------ - -- Digit conversion support -- - ------------------------------ - - -- types & constants - - subtype S_digit_chars is character range '0' to '9'; - subtype S_digits is integer range 0 to 9 ; - - type T_digit_chars_map is array(S_digit_chars) of S_digits; - - constant C_DIGIT_CHARS_MAP: T_digit_chars_map - := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - - type T_digits_map is array(S_digits) of S_digit_chars; - - constant C_DIGITS_MAP: T_digits_map - := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); - - - -------------------------------- - -- Decimal conversion support -- - -------------------------------- - - -- unsigned to decimal - - function U_To_d (Arg: string) return integer is - constant Argument: string(Arg'length downto 1) := Arg; - variable Result: integer := 0; - begin - for i in Argument'range loop - case Argument(i) is when '1' => Result := 2**(i-1) + Result; - when '0' => null; - when others => return(-1); - end case; - end loop; - return (Result); - end U_To_d; - - -- signed to decimal - - function S_To_d (Arg: string) return integer is - constant Argument: string(Arg'length downto 1) := Arg; - variable Result: integer := 0; - begin - case Argument(Argument'left) is - when '1' => Result := - 2**(Argument'left-1); - when '0' => Result := 0; - when others => return (integer'low); - end case; - for i in Argument'left-1 downto 1 loop - case Argument(i) is when '1' => Result := 2**(i-1) + Result; - when '0' => null; - when others => return(integer'low); - end case; - end loop; - return (Result); - end S_To_d; - - -- string to decimal - - function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is - constant Sign: character := Arg(1); - constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length); - variable Char: character; - variable Result: integer := 0; - begin - Result := 0; - for i in Value'range loop - Result := Result * 10; - Char := Value(i); - if (Char /= ' ') then - Result := Result + C_DIGIT_CHARS_MAP(Char); - end if; - end loop; - case Sign is when '-' => return(-Result); - when others => return(Result); - end case; - end I_To_d; - - -- boolean (0,1) to decimal - - function B_To_d (Arg: string(1 to 1)) return integer is - begin - case Arg is when "1" => return(1); - when "0" => return(0); - when others => return(-1); - end case; - end B_To_d; - - -- boolean (T,F) to decimal - - function L_To_d (Arg: string(1 to 1)) return integer is - begin - case Arg is when "T" => return(1); - when others => return(0); - end case; - end L_To_d; - - - - ---------------------------- - -- Hex conversion support -- - ---------------------------- - - -- Constants & types - - constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?"; - - -- Function to return Hex index of a nibble - - function U_To_h_Index(Arg: string(4 downto 1)) return integer is - variable Index: integer := 0; - begin - for i in Arg'range loop - case Arg(i) is when '1' => Index := 2**(i-1) + Index; - when '0' => null; - when others => return (17); - end case; - end loop; - return (Index+1); - end U_To_h_Index; - - -- Hex conversion - - function U_To_h (Arg: string) return string is - variable Result: string((Arg'length-1)/4 +1 downto 1); - variable ExtArg: string(Result'length*4 downto 1) := (others => '0'); - begin - ExtArg(Arg'length downto 1) := Arg; - for i in Result'range loop - Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) )); - end loop; - return (FIO_h_PRE & Result & FIO_h_POST); - end U_To_h; - - - - ---------------------------- - -- Bit conversion support -- - ---------------------------- - - function L_To_b (Arg: string(1 to 1)) return string is - variable Result: string(1 to 1); - begin - case Arg is when "T" => Result := "1"; - when others => Result := "0"; - end case; - return(FIO_b_PRE & Result & FIO_b_POST); - end L_To_b; - - - function I_To_b (Arg: string(1 to FIO_d_WIDTH+1); - Justified: side; - Width: integer) return string is - - variable IntValue: integer := I_To_d(Arg); - variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' '); - variable Sign: character := ' '; - constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' '); - variable BitWidth: integer range 0 to FIO_b_WIDTH; - variable MsPos: integer range 1 to BitValue'length; - variable BitValueExtended: string(1 to 2*FIO_b_WIDTH); - - begin - - if (IntValue < 0) then - Sign := '-'; - IntValue := -IntValue; - end if; - - for i in BitValue'reverse_range loop - BitValue(i) := C_DIGITS_MAP(IntValue mod 2); - IntValue := IntValue / 2; - exit when (IntValue = 0); - end loop; - - BitValueExtended := BitValue & Blanks; - - if (Width = 0) or (Width > FIO_b_WIDTH+1) then - BitWidth := FIO_b_WIDTH; - else - BitWidth := Width-1; - end if; - - if (Justified = RIGHT) then - return (FIO_bv_PRE & - Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) & - FIO_bv_POST); - else - for i in BitValue'range loop - if BitValue(i) /= ' ' then - MSPos := i; - exit; - end if; - end loop; - return (FIO_bv_PRE & - Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) & - FIO_bv_POST); - end if; - - end I_To_b; - - - ----------------------------------- - -- Reasonable conversion support -- - ----------------------------------- - - function I_To_r (Arg: string(1 to FIO_d_WIDTH+1); - Justified: side; - Width: integer) return string is - constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1); - constant Sign: character := Arg(1); - constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' '); - variable IntWidth: integer range 0 to FIO_d_WIDTH; - variable MsPos: integer range 1 to Value'length; - variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks; - begin - if (Width = 0) or (Width > FIO_d_WIDTH+1) then - IntWidth := FIO_d_WIDTH; - else - IntWidth := Width-1; - end if; - if (Justified = RIGHT) then - return (Sign & Value(Value'length-IntWidth+1 to Value'length)); - else - for i in Value'range loop - if Value(i) /= ' ' then - MSPos := i; - exit; - end if; - end loop; - return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1)); - end if; - end I_To_r; - - - ------------------------------------------- - -- Reasonable output conversion function -- - ------------------------------------------- - - function ReasonableOutput (Arg: string; - Justified: side; - Width: integer) return string is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:" | "S:" | "V:" => - return U_To_h(Value); - when "I:" => - return I_To_r(Value, Justified, Width); - when "B:" | "L:" | "C:" => - return Value; - when others => - return Argument; - end case; - - end ReasonableOutput; - - - ------------------------------------ - -- Bit output conversion function -- - ------------------------------------ - - function BitOutput (Arg: string; - Justified: side; - Width: integer) return string is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:" | "S:" | "V:" => - return (FIO_bv_PRE & Value & FIO_bv_POST); - when "B:" => - -- Value(1 to 1) instead of Value for LeapFrog - return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST); - when "I:" => - return I_To_b(Value, Justified, Width); - when "L:" => - -- Value(1 to 1) instead of Value for LeapFrog - return L_To_b(Value(1 to 1)); - when others => - return Argument; - end case; - - end BitOutput; - - - ------------------------------------------- - -- Decimal output conversion function -- - ------------------------------------------- - - function DecimalOutput (Arg: string) return integer is - constant Argument: string(1 to Arg'length) := Arg; - constant TypeSpec: string (1 to 2) := Argument(1 to 2); - constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); - begin - case TypeSpec is - when "U:"| "V:" => - return U_To_d(Value); - when "S:" => - return S_To_d(Value); - when "I:" => - return I_To_d(Value); - when "B:" => - return B_To_d(Value); - when "L:" => - return L_To_d(Value); - when others => - return integer'low; - end case; - - end DecimalOutput; - - - ---------------------------- - -- Atomic print functions -- - ---------------------------- - - -- test for end of format string - - function FIO_EOS (Format: in string; - Pointer: in integer) - return boolean is - begin - return (Pointer > Format'length); - end FIO_EOS; - - - -- Atomic value print function - - procedure FIO_PrintValue (file F: text; - L: inout line; - Format: in string; - Pointer: inout integer; - Last: in boolean := FALSE) is - variable Char: character; - begin - while (not FIO_EOS(Format, Pointer)) loop - Char := Format(Pointer); - case Char is - when '\' => - Pointer := Pointer + 1; - exit when (FIO_EOS(Format, Pointer)); - Char := Format(Pointer); - case Char is when 'n' => writeline(F, L); - when others => write(L, Char); - end case; - when '%' => - if Last then - FIO_Warning_Fsbla(F, L, Format, Pointer); - end if; - Pointer := Pointer + 1; - exit; - when others => - write(L, char); - end case; - Pointer := Pointer + 1; - end loop; - end FIO_PrintValue; - - - ---- Atomic argument print function - - procedure FIO_PrintArg (file F: text; - L: inout line; - Format: in string; - Pointer: inout integer; - Arg: in string) is - variable Char: character; - variable Justified: side; - variable Width: integer; - - begin - - FIO_PrintValue(F, L, Format, Pointer); - - Justified := RIGHT; - Width := 0; - while (not FIO_EOS(Format, Pointer)) loop - Char := Format(Pointer); - case Char is - when '-' => - Justified := LEFT; - Pointer := Pointer + 1; - when '0' to '9' => - Width := Width*10 + C_DIGIT_CHARS_MAP(Char); - Pointer := Pointer + 1; - when 'r' => - write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'b' => - write(L, BitOutput(Arg, Justified, Width), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'd' => - write(L, DecimalOutput(Arg), Justified, Width); - Pointer := Pointer + 1; - exit; - when 'q' | 's' => - write(L, Arg, Justified, Width); - Pointer := Pointer + 1; - exit; - when others => - FIO_Warning_Ufs(F, L, Format, Pointer, Char); - write(L, Arg, Justified, Width); - Pointer := Pointer + 1; - exit; - end case; - end loop; - end FIO_PrintArg; - - - ----------------------------------------------------- - -- The format string iteration expansion procedure -- - ----------------------------------------------------- - - procedure FIO_FormatExpand (FMT: inout line; - Format: in string; - StartPointer: in positive) is - - variable Pointer: positive := StartPointer; - variable TokenStart: positive; - variable IterStringStart: positive; - variable IterStringEnd: positive; - variable IterCount: natural; - variable OpenBrackets: natural; - variable L: line; - - begin - - FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - - -- look for format specifier - when '%' => - - -- initialize iteration token search - TokenStart := Pointer; - IterCount := 0; - Pointer := Pointer + 1; - - -- start iteration token search - TOKEN_READ: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - - -- read iteration counter - when '0' to '9' => - IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer)); - Pointer := Pointer + 1; - - -- expect open bracket - when '{' => - - -- initialize iteration string read - OpenBrackets := 1; - IterStringStart := Pointer + 1; - Pointer := Pointer + 1; - -- quit prematurely when iteration count is 0 - next FORMAT_SEARCH when (IterCount = 0); - - -- start iteration string read - ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop - - case Format(Pointer) is - -- keep track of open brackets - when '{' => - OpenBrackets := OpenBrackets + 1; - Pointer := Pointer + 1; - -- when closing bracket is found, process iteration string - when '}' => - OpenBrackets := OpenBrackets - 1; - if (OpenBrackets = 0) then - IterStringEnd := Pointer-1; - if (TokenStart /= 1) then - write(L, Format(1 to TokenStart-1)); - end if; - for i in 1 to IterCount loop - write(L, Format(IterStringStart to IterStringEnd)); - end loop; - if (IterStringEnd /= Format'length) then - write(L, Format(IterStringEnd+2 to Format'length)); - end if; - -- call expansion procedure recursively on expanded format - FIO_FormatExpand(FMT, L.all, TokenStart); - deallocate(L); - return; - end if; - Pointer := Pointer + 1; - -- skip escaped characters - when '\' => - Pointer := Pointer + 2; - -- read iteration string - when others => - Pointer := Pointer + 1; - - end case; - - end loop ITER_STRING_READ; - - -- stop iteration token search when no opening bracket found - when others => - Pointer := Pointer + 1; - next FORMAT_SEARCH; - - end case; - - end loop TOKEN_READ; - - -- skip escaped characters - when '\' => - Pointer := Pointer + 2; - - -- read other characters - when others => - Pointer := Pointer + 1; - - end case; - - end loop FORMAT_SEARCH; - - write(FMT, Format); - deallocate(L); - - end FIO_FormatExpand; - - - - -------------------------- - -- The fprint procedure -- - -------------------------- - - procedure fprint - (file F: text; - L: inout line; - Format: in string; - A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; - A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; - A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; - A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL - ) is - - variable Pointer: integer; - variable FMT: line; - - begin - - Pointer := 1; - - FIO_FormatExpand (FMT, Format, Format'low); - - if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 ); - if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 ); - if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 ); - if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 ); - if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 ); - if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 ); - if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 ); - if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 ); - if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 ); - if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10); - if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11); - if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12); - if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13); - if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14); - if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15); - if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16); - if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17); - if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18); - if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19); - if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20); - if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21); - if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22); - if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23); - if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24); - if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25); - if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26); - if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27); - if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28); - if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29); - if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30); - if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31); - if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32); - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - end if; end if; end if; end if; end if; end if; end if; end if; - - FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE); - - deallocate(FMT); - - end fprint; - - - ------------------------------------------- - -- Formatted output conversion functions -- - ------------------------------------------- - - function fo (Arg: unsigned) return string is - constant Argument: unsigned(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("U:" & Result); - end fo; - - function fo (Arg: signed) return string is - constant Argument: signed(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("S:" & Result); - end fo; - - function fo (Arg: std_logic_vector) return string is - constant Argument: std_logic_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: std_ulogic_vector) return string is - constant Argument: std_ulogic_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_STD_LOGIC_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: bit_vector) return string is - constant Argument: bit_vector(1 to Arg'length) := Arg; - variable Result: string(1 to Arg'length); - begin - for i in Argument'range loop - Result(i) := C_BIT_MAP(Argument(i)); - end loop; - return ("V:" & Result); - end fo; - - function fo (Arg: integer) return string is - variable Argument: integer := Arg; - variable Result: string(1 to FIO_d_WIDTH) := (others => ' '); - variable Sign: character := ' '; - begin - if (Argument < 0) and (Argument /= integer'low) then - Sign := '-'; - Argument := -Argument; - end if; - for i in Result'reverse_range loop - Result(i) := C_DIGITS_MAP(Argument mod 10); - Argument := Argument / 10; - exit when (Argument = 0); - end loop; - return ("I:" & Sign & Result); - end fo; - - function fo (Arg: std_ulogic) return string is - begin - return ("B:" & C_STD_LOGIC_MAP(Arg)); - end fo; - - function fo (Arg: bit) return string is - begin - return ("B:" & C_BIT_MAP(Arg)); - end fo; - - function fo (Arg: boolean) return string is - begin - if (ARG = TRUE) then - return ("L:T"); - else - return ("L:F"); - end if; - end fo; - - function fo (Arg: character) return string is - begin - return ("C:" & Arg); - end fo; - - -- auxilary function fgets(Arg :string) - -- returns index of first NUL in Arg or if no NUL is present just Arg'length - -- goes through Arg from 1 to Arg'length - function fgets (Arg: string) return integer is - variable index: integer := Arg'length; - begin - for i in 1 to Arg'length loop - if Arg(i) = NUL then - index := i - 1; - exit; - else - null; - end if; - end loop; - return index; - end fgets; - - -- returns the Arg string until the first NUL was encountered - -- if fo is used on a string with NUL in it it will stop reading the rest - -- of the string, even if a larger field width has been supplied. fo will - -- then just pad the remaining characters with blanco's - function fo (Arg: string) return string is - begin - return Arg(1 to fgets(Arg)); - end fo; - - function fo (Arg: time) return string is - begin - return fo (integer (Arg / 1 ns)); - end fo; - -end PCK_FIO; - +---- $Id: PCK_FIO_1993_BODY.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + + package body PCK_FIO is + + -------------------------- + -- FIO Warnings support -- + -------------------------- + + procedure FIO_Warning_Fsbla (file F: text; + L: inout line; + Format: in string; + Pointer: in positive) is + begin + fprint (F, L, "\n** Warning: FIO_PrintLastValue: " & + "Format specifier beyond last argument\n"); + fprint (F, L, "** in format string: ""%s""\n", Format); + fprint (F, L, "** "); + for i in 1 to Pointer-1 loop + fprint (F, L, "-"); + end loop; + fprint (F, L, "^\n"); + end FIO_Warning_Fsbla; + + procedure FIO_Warning_Ufs (file F: text; + L: inout line; + Format: in string; + Pointer: in positive; + Char: in character) is + begin + fprint (F, L, "\n** Warning: FIO_PrintArg: " & + "Unexpected format specifier '%r'\n", + fo(Char)); + fprint (F, L, "** in format string: ""%s""\n", Format) ; + fprint (F, L, "** "); + for i in 1 to Pointer-1 loop + fprint (F, L, "-"); + end loop; + fprint (F, L, "^\n** Assuming 'q' to proceed: "); + end FIO_Warning_Ufs; + + + ---------------------------------- + -- bit conversion support -- + ---------------------------------- + + type T_bit_map is array(bit) of character; + + constant C_BIT_MAP: T_bit_map + := ('0', '1'); + + ---------------------------------- + -- std_logic conversion support -- + ---------------------------------- + + type T_std_logic_map is array(std_ulogic) of character; + + constant C_STD_LOGIC_MAP: T_std_logic_map + := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); + + ------------------------------ + -- Digit conversion support -- + ------------------------------ + + -- types & constants + + subtype S_digit_chars is character range '0' to '9'; + subtype S_digits is integer range 0 to 9 ; + + type T_digit_chars_map is array(S_digit_chars) of S_digits; + + constant C_DIGIT_CHARS_MAP: T_digit_chars_map + := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + + type T_digits_map is array(S_digits) of S_digit_chars; + + constant C_DIGITS_MAP: T_digits_map + := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + + -------------------------------- + -- Decimal conversion support -- + -------------------------------- + + -- unsigned to decimal + + function U_To_d (Arg: string) return integer is + constant Argument: string(Arg'length downto 1) := Arg; + variable Result: integer := 0; + begin + for i in Argument'range loop + case Argument(i) is when '1' => Result := 2**(i-1) + Result; + when '0' => null; + when others => return(-1); + end case; + end loop; + return (Result); + end U_To_d; + + -- signed to decimal + + function S_To_d (Arg: string) return integer is + constant Argument: string(Arg'length downto 1) := Arg; + variable Result: integer := 0; + begin + case Argument(Argument'left) is + when '1' => Result := - 2**(Argument'left-1); + when '0' => Result := 0; + when others => return (integer'low); + end case; + for i in Argument'left-1 downto 1 loop + case Argument(i) is when '1' => Result := 2**(i-1) + Result; + when '0' => null; + when others => return(integer'low); + end case; + end loop; + return (Result); + end S_To_d; + + -- string to decimal + + function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is + constant Sign: character := Arg(1); + constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length); + variable Char: character; + variable Result: integer := 0; + begin + Result := 0; + for i in Value'range loop + Result := Result * 10; + Char := Value(i); + if (Char /= ' ') then + Result := Result + C_DIGIT_CHARS_MAP(Char); + end if; + end loop; + case Sign is when '-' => return(-Result); + when others => return(Result); + end case; + end I_To_d; + + -- boolean (0,1) to decimal + + function B_To_d (Arg: string(1 to 1)) return integer is + begin + case Arg is when "1" => return(1); + when "0" => return(0); + when others => return(-1); + end case; + end B_To_d; + + -- boolean (T,F) to decimal + + function L_To_d (Arg: string(1 to 1)) return integer is + begin + case Arg is when "T" => return(1); + when others => return(0); + end case; + end L_To_d; + + + + ---------------------------- + -- Hex conversion support -- + ---------------------------- + + -- Constants & types + + constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?"; + + -- Function to return Hex index of a nibble + + function U_To_h_Index(Arg: string(4 downto 1)) return integer is + variable Index: integer := 0; + begin + for i in Arg'range loop + case Arg(i) is when '1' => Index := 2**(i-1) + Index; + when '0' => null; + when others => return (17); + end case; + end loop; + return (Index+1); + end U_To_h_Index; + + -- Hex conversion + + function U_To_h (Arg: string) return string is + variable Result: string((Arg'length-1)/4 +1 downto 1); + variable ExtArg: string(Result'length*4 downto 1) := (others => '0'); + begin + ExtArg(Arg'length downto 1) := Arg; + for i in Result'range loop + Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) )); + end loop; + return (FIO_h_PRE & Result & FIO_h_POST); + end U_To_h; + + + + ---------------------------- + -- Bit conversion support -- + ---------------------------- + + function L_To_b (Arg: string(1 to 1)) return string is + variable Result: string(1 to 1); + begin + case Arg is when "T" => Result := "1"; + when others => Result := "0"; + end case; + return(FIO_b_PRE & Result & FIO_b_POST); + end L_To_b; + + + function I_To_b (Arg: string(1 to FIO_d_WIDTH+1); + Justified: side; + Width: integer) return string is + + variable IntValue: integer := I_To_d(Arg); + variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' '); + variable Sign: character := ' '; + constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' '); + variable BitWidth: integer range 0 to FIO_b_WIDTH; + variable MsPos: integer range 1 to BitValue'length; + variable BitValueExtended: string(1 to 2*FIO_b_WIDTH); + + begin + + if (IntValue < 0) then + Sign := '-'; + IntValue := -IntValue; + end if; + + for i in BitValue'reverse_range loop + BitValue(i) := C_DIGITS_MAP(IntValue mod 2); + IntValue := IntValue / 2; + exit when (IntValue = 0); + end loop; + + BitValueExtended := BitValue & Blanks; + + if (Width = 0) or (Width > FIO_b_WIDTH+1) then + BitWidth := FIO_b_WIDTH; + else + BitWidth := Width-1; + end if; + + if (Justified = RIGHT) then + return (FIO_bv_PRE & + Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) & + FIO_bv_POST); + else + for i in BitValue'range loop + if BitValue(i) /= ' ' then + MSPos := i; + exit; + end if; + end loop; + return (FIO_bv_PRE & + Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) & + FIO_bv_POST); + end if; + + end I_To_b; + + + ----------------------------------- + -- Reasonable conversion support -- + ----------------------------------- + + function I_To_r (Arg: string(1 to FIO_d_WIDTH+1); + Justified: side; + Width: integer) return string is + constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1); + constant Sign: character := Arg(1); + constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' '); + variable IntWidth: integer range 0 to FIO_d_WIDTH; + variable MsPos: integer range 1 to Value'length; + variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks; + begin + if (Width = 0) or (Width > FIO_d_WIDTH+1) then + IntWidth := FIO_d_WIDTH; + else + IntWidth := Width-1; + end if; + if (Justified = RIGHT) then + return (Sign & Value(Value'length-IntWidth+1 to Value'length)); + else + for i in Value'range loop + if Value(i) /= ' ' then + MSPos := i; + exit; + end if; + end loop; + return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1)); + end if; + end I_To_r; + + + ------------------------------------------- + -- Reasonable output conversion function -- + ------------------------------------------- + + function ReasonableOutput (Arg: string; + Justified: side; + Width: integer) return string is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:" | "S:" | "V:" => + return U_To_h(Value); + when "I:" => + return I_To_r(Value, Justified, Width); + when "B:" | "L:" | "C:" => + return Value; + when others => + return Argument; + end case; + + end ReasonableOutput; + + + ------------------------------------ + -- Bit output conversion function -- + ------------------------------------ + + function BitOutput (Arg: string; + Justified: side; + Width: integer) return string is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:" | "S:" | "V:" => + return (FIO_bv_PRE & Value & FIO_bv_POST); + when "B:" => + -- Value(1 to 1) instead of Value for LeapFrog + return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST); + when "I:" => + return I_To_b(Value, Justified, Width); + when "L:" => + -- Value(1 to 1) instead of Value for LeapFrog + return L_To_b(Value(1 to 1)); + when others => + return Argument; + end case; + + end BitOutput; + + + ------------------------------------------- + -- Decimal output conversion function -- + ------------------------------------------- + + function DecimalOutput (Arg: string) return integer is + constant Argument: string(1 to Arg'length) := Arg; + constant TypeSpec: string (1 to 2) := Argument(1 to 2); + constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); + begin + case TypeSpec is + when "U:"| "V:" => + return U_To_d(Value); + when "S:" => + return S_To_d(Value); + when "I:" => + return I_To_d(Value); + when "B:" => + return B_To_d(Value); + when "L:" => + return L_To_d(Value); + when others => + return integer'low; + end case; + + end DecimalOutput; + + + ---------------------------- + -- Atomic print functions -- + ---------------------------- + + -- test for end of format string + + function FIO_EOS (Format: in string; + Pointer: in integer) + return boolean is + begin + return (Pointer > Format'length); + end FIO_EOS; + + + -- Atomic value print function + + procedure FIO_PrintValue (file F: text; + L: inout line; + Format: in string; + Pointer: inout integer; + Last: in boolean := FALSE) is + variable Char: character; + begin + while (not FIO_EOS(Format, Pointer)) loop + Char := Format(Pointer); + case Char is + when '\' => + Pointer := Pointer + 1; + exit when (FIO_EOS(Format, Pointer)); + Char := Format(Pointer); + case Char is when 'n' => writeline(F, L); + when others => write(L, Char); + end case; + when '%' => + if Last then + FIO_Warning_Fsbla(F, L, Format, Pointer); + end if; + Pointer := Pointer + 1; + exit; + when others => + write(L, char); + end case; + Pointer := Pointer + 1; + end loop; + end FIO_PrintValue; + + + ---- Atomic argument print function + + procedure FIO_PrintArg (file F: text; + L: inout line; + Format: in string; + Pointer: inout integer; + Arg: in string) is + variable Char: character; + variable Justified: side; + variable Width: integer; + + begin + + FIO_PrintValue(F, L, Format, Pointer); + + Justified := RIGHT; + Width := 0; + while (not FIO_EOS(Format, Pointer)) loop + Char := Format(Pointer); + case Char is + when '-' => + Justified := LEFT; + Pointer := Pointer + 1; + when '0' to '9' => + Width := Width*10 + C_DIGIT_CHARS_MAP(Char); + Pointer := Pointer + 1; + when 'r' => + write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'b' => + write(L, BitOutput(Arg, Justified, Width), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'd' => + write(L, DecimalOutput(Arg), Justified, Width); + Pointer := Pointer + 1; + exit; + when 'q' | 's' => + write(L, Arg, Justified, Width); + Pointer := Pointer + 1; + exit; + when others => + FIO_Warning_Ufs(F, L, Format, Pointer, Char); + write(L, Arg, Justified, Width); + Pointer := Pointer + 1; + exit; + end case; + end loop; + end FIO_PrintArg; + + + ----------------------------------------------------- + -- The format string iteration expansion procedure -- + ----------------------------------------------------- + + procedure FIO_FormatExpand (FMT: inout line; + Format: in string; + StartPointer: in positive) is + + variable Pointer: positive := StartPointer; + variable TokenStart: positive; + variable IterStringStart: positive; + variable IterStringEnd: positive; + variable IterCount: natural; + variable OpenBrackets: natural; + variable L: line; + + begin + + FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + + -- look for format specifier + when '%' => + + -- initialize iteration token search + TokenStart := Pointer; + IterCount := 0; + Pointer := Pointer + 1; + + -- start iteration token search + TOKEN_READ: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + + -- read iteration counter + when '0' to '9' => + IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer)); + Pointer := Pointer + 1; + + -- expect open bracket + when '{' => + + -- initialize iteration string read + OpenBrackets := 1; + IterStringStart := Pointer + 1; + Pointer := Pointer + 1; + -- quit prematurely when iteration count is 0 + next FORMAT_SEARCH when (IterCount = 0); + + -- start iteration string read + ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop + + case Format(Pointer) is + -- keep track of open brackets + when '{' => + OpenBrackets := OpenBrackets + 1; + Pointer := Pointer + 1; + -- when closing bracket is found, process iteration string + when '}' => + OpenBrackets := OpenBrackets - 1; + if (OpenBrackets = 0) then + IterStringEnd := Pointer-1; + if (TokenStart /= 1) then + write(L, Format(1 to TokenStart-1)); + end if; + for i in 1 to IterCount loop + write(L, Format(IterStringStart to IterStringEnd)); + end loop; + if (IterStringEnd /= Format'length) then + write(L, Format(IterStringEnd+2 to Format'length)); + end if; + -- call expansion procedure recursively on expanded format + FIO_FormatExpand(FMT, L.all, TokenStart); + deallocate(L); + return; + end if; + Pointer := Pointer + 1; + -- skip escaped characters + when '\' => + Pointer := Pointer + 2; + -- read iteration string + when others => + Pointer := Pointer + 1; + + end case; + + end loop ITER_STRING_READ; + + -- stop iteration token search when no opening bracket found + when others => + Pointer := Pointer + 1; + next FORMAT_SEARCH; + + end case; + + end loop TOKEN_READ; + + -- skip escaped characters + when '\' => + Pointer := Pointer + 2; + + -- read other characters + when others => + Pointer := Pointer + 1; + + end case; + + end loop FORMAT_SEARCH; + + write(FMT, Format); + deallocate(L); + + end FIO_FormatExpand; + + + + -------------------------- + -- The fprint procedure -- + -------------------------- + + procedure fprint + (file F: text; + L: inout line; + Format: in string; + A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; + A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; + A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; + A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL + ) is + + variable Pointer: integer; + variable FMT: line; + + begin + + Pointer := 1; + + FIO_FormatExpand (FMT, Format, Format'low); + + if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 ); + if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 ); + if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 ); + if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 ); + if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 ); + if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 ); + if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 ); + if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 ); + if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 ); + if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10); + if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11); + if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12); + if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13); + if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14); + if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15); + if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16); + if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17); + if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18); + if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19); + if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20); + if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21); + if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22); + if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23); + if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24); + if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25); + if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26); + if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27); + if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28); + if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29); + if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30); + if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31); + if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32); + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + end if; end if; end if; end if; end if; end if; end if; end if; + + FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE); + + deallocate(FMT); + + end fprint; + + + ------------------------------------------- + -- Formatted output conversion functions -- + ------------------------------------------- + + function fo (Arg: unsigned) return string is + constant Argument: unsigned(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("U:" & Result); + end fo; + + function fo (Arg: signed) return string is + constant Argument: signed(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("S:" & Result); + end fo; + + function fo (Arg: std_logic_vector) return string is + constant Argument: std_logic_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: std_ulogic_vector) return string is + constant Argument: std_ulogic_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_STD_LOGIC_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: bit_vector) return string is + constant Argument: bit_vector(1 to Arg'length) := Arg; + variable Result: string(1 to Arg'length); + begin + for i in Argument'range loop + Result(i) := C_BIT_MAP(Argument(i)); + end loop; + return ("V:" & Result); + end fo; + + function fo (Arg: integer) return string is + variable Argument: integer := Arg; + variable Result: string(1 to FIO_d_WIDTH) := (others => ' '); + variable Sign: character := ' '; + begin + if (Argument < 0) and (Argument /= integer'low) then + Sign := '-'; + Argument := -Argument; + end if; + for i in Result'reverse_range loop + Result(i) := C_DIGITS_MAP(Argument mod 10); + Argument := Argument / 10; + exit when (Argument = 0); + end loop; + return ("I:" & Sign & Result); + end fo; + + function fo (Arg: std_ulogic) return string is + begin + return ("B:" & C_STD_LOGIC_MAP(Arg)); + end fo; + + function fo (Arg: bit) return string is + begin + return ("B:" & C_BIT_MAP(Arg)); + end fo; + + function fo (Arg: boolean) return string is + begin + if (ARG = TRUE) then + return ("L:T"); + else + return ("L:F"); + end if; + end fo; + + function fo (Arg: character) return string is + begin + return ("C:" & Arg); + end fo; + + -- auxilary function fgets(Arg :string) + -- returns index of first NUL in Arg or if no NUL is present just Arg'length + -- goes through Arg from 1 to Arg'length + function fgets (Arg: string) return integer is + variable index: integer := Arg'length; + begin + for i in 1 to Arg'length loop + if Arg(i) = NUL then + index := i - 1; + exit; + else + null; + end if; + end loop; + return index; + end fgets; + + -- returns the Arg string until the first NUL was encountered + -- if fo is used on a string with NUL in it it will stop reading the rest + -- of the string, even if a larger field width has been supplied. fo will + -- then just pad the remaining characters with blanco's + function fo (Arg: string) return string is + begin + return Arg(1 to fgets(Arg)); + end fo; + + function fo (Arg: time) return string is + begin + return fo (integer (Arg / 1 ns)); + end fo; + +end PCK_FIO; + diff --git a/lib/PCK_FIO-2002.7/README b/lib/PCK_FIO-2002.7/README index b16c6c5..9060484 100644 --- a/lib/PCK_FIO-2002.7/README +++ b/lib/PCK_FIO-2002.7/README @@ -1,88 +1,88 @@ ----- $Id: README,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - -Version 2002.07 -=============== - -Contents -======== - -This distribution contains the following files: - - PCK_FIO_1987.vhd: VHDL-87 source of the header of the PCK_FIO package - PCK_FIO_1987_BODY.vhd: VHDL-87 source of the body of the PCK_FIO package - PCK_FIO_1993.vhd: VHDL-93 source of the header of the PCK_FIO package - PCK_FIO_1993_BODY.vhd: VHDL-93 source of the body of the PCK_FIO package - TB_PCK_FIO_1987.vhd: VHDL-87 source of the testbench for package PCK_FIO - TB_PCK_FIO_1993.vhd: VHDL-93 source of the testbench for package PCK_FIO - PCK_FIO.out.gold: Certified test bench output - PCK_FIO.html: Manual for PCK_FIO in html format - README: This file - - -Installation -============ - -VHDL-1987 ---------- -To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and -analyze the VHDL file PCK_FIO_1987.vhd and PCK_FIO_1987_BODY.vhd into this library. - -To install the test bench, analyze TB_PCK_FIO_1987.vhd into the same library. - -VHDL-1993 ---------- -To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and -analyze the VHDL file PCK_FIO_1993.vhd and PCK_FIO_1993_BODY.vhd into this library. - -To install the test bench, analyze TB_PCK_FIO_1993.vhd into the same library. - -Numeric packages ----------------- -If you want to use IEEE.std_logic_arith instead of IEEE.numeric_std, you need -to edit the source code of the package, both header and body, and the test bench -and replace the package use clause. PCK_FIO works with either of these packages. - -Documentation -------------- -To install the documentation, put the file point PCK_FIO.html in a path of -your choosing, point your web browser to it, and bookmark it. - - -Installation check -================== - -After installing the test bench, you should run it. The corresponding VHDL -design unit is EASICS_PACKAGES.TBE_PCK_FIO(TB). - -Simulating the test bench should create a file called PCK_FIO.out. This file -should be identical to PCK_FIO.out.gold. Any difference indicates a portability -issue or a simulator non-compliance or bug. - - - - +---- $Id: README,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + +Version 2002.07 +=============== + +Contents +======== + +This distribution contains the following files: + + PCK_FIO_1987.vhd: VHDL-87 source of the header of the PCK_FIO package + PCK_FIO_1987_BODY.vhd: VHDL-87 source of the body of the PCK_FIO package + PCK_FIO_1993.vhd: VHDL-93 source of the header of the PCK_FIO package + PCK_FIO_1993_BODY.vhd: VHDL-93 source of the body of the PCK_FIO package + TB_PCK_FIO_1987.vhd: VHDL-87 source of the testbench for package PCK_FIO + TB_PCK_FIO_1993.vhd: VHDL-93 source of the testbench for package PCK_FIO + PCK_FIO.out.gold: Certified test bench output + PCK_FIO.html: Manual for PCK_FIO in html format + README: This file + + +Installation +============ + +VHDL-1987 +--------- +To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and +analyze the VHDL file PCK_FIO_1987.vhd and PCK_FIO_1987_BODY.vhd into this library. + +To install the test bench, analyze TB_PCK_FIO_1987.vhd into the same library. + +VHDL-1993 +--------- +To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and +analyze the VHDL file PCK_FIO_1993.vhd and PCK_FIO_1993_BODY.vhd into this library. + +To install the test bench, analyze TB_PCK_FIO_1993.vhd into the same library. + +Numeric packages +---------------- +If you want to use IEEE.std_logic_arith instead of IEEE.numeric_std, you need +to edit the source code of the package, both header and body, and the test bench +and replace the package use clause. PCK_FIO works with either of these packages. + +Documentation +------------- +To install the documentation, put the file point PCK_FIO.html in a path of +your choosing, point your web browser to it, and bookmark it. + + +Installation check +================== + +After installing the test bench, you should run it. The corresponding VHDL +design unit is EASICS_PACKAGES.TBE_PCK_FIO(TB). + +Simulating the test bench should create a file called PCK_FIO.out. This file +should be identical to PCK_FIO.out.gold. Any difference indicates a portability +issue or a simulator non-compliance or bug. + + + + diff --git a/lib/PCK_FIO-2002.7/TB_PCK_FIO_1987.vhd b/lib/PCK_FIO-2002.7/TB_PCK_FIO_1987.vhd index 2e18ff4..0890ba5 100644 --- a/lib/PCK_FIO-2002.7/TB_PCK_FIO_1987.vhd +++ b/lib/PCK_FIO-2002.7/TB_PCK_FIO_1987.vhd @@ -1,531 +1,531 @@ ----- $Id: TB_PCK_FIO_1987.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - -library IEEE; -use IEEE.std_logic_1164.all; --- signed/unsigned definition: use either std_logic_arith or numeric_std --- use IEEE.std_logic_arith.all; -- the Synopsys one - use IEEE.numeric_std.all; - -use STD.TEXTIO.all; - -library EASICS_PACKAGES; -use EASICS_PACKAGES.PCK_FIO.all; - -entity TBE_PCK_FIO is - -end TBE_PCK_FIO; - -architecture TB of TBE_PCK_FIO is - -begin - -USAGE: process - - file RESULT: text is out "PCK_FIO.out"; - variable L: line; - variable Pointer: integer; - variable BoolTrue: boolean := TRUE; - variable BoolFalse: boolean := FALSE; - variable IntPos: integer := 5678; - variable BigIntPos: integer := 12345678; - variable IntNeg: integer := -8765; - variable BigIntNeg: integer := -87654321; - variable Uns: unsigned(6 downto 0) := unsigned'("1010010"); - variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10"); - variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010"); - variable SigPos: signed(6 downto 0) := signed'("0010010"); - variable SigNeg: signed(6 downto 0) := signed'("1010010"); - variable BitX: std_logic := 'X'; - variable Bit1: std_logic := '1'; - variable Bit0: std_logic := '0'; - - variable parameter_1: integer := 1234; - variable parameter_2: integer := 2345; - variable parameter_3: integer := 4567; - - constant TempString: string :="ABC" & NUL & "DEF"; -begin - -fprint(RESULT, L, - "PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" & - "-----------------------------------------\n\n" & - "This is the result of running the PCK_FIO testbench.\n" & - "This file should be compared with PCK_FIO.out.gold, which is\n" & - "the reference output. Any difference indicates a portability\n" & - "issue or a simulator non-compliance or bug.\n\n" - ); - - -fprint(RESULT, L, - "\n--------------------\n" & - "-- Basic features --\n" & - "--------------------\n\n" - ); - -fprint(RESULT, L, - "-- First some auxiliary declarations\n" - ); - -fprint(RESULT, L, - "> file RESULT: text is out ""PCK_FIO.out"";\n" & - "> variable L: line;\n" & - "> variable BoolTrue: boolean := TRUE;\n" & - "> variable BoolFalse: boolean := FALSE;\n" & - "> variable IntPos: integer := 5678;\n" & - "> variable BigIntPos: integer := 12345678;\n" & - "> variable IntNeg: integer := -8765;\n" & - "> variable BigIntNeg: integer := -87654321;\n" & - "> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" & - "> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" & - "> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" & - "> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" & - "> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" & - "> variable BitX: std_logic := 'X';\n" & - "> variable Bit1: std_logic := '1';\n" & - "> variable Bit0: std_logic := '0';\n" & - "> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n" -); - - -fprint(RESULT, L, - "\n\n-- fprint call with no arguments\n" & - "> fprint(RESULT, L, ""No arguments.\\n"");\n" - ); -fprint(RESULT, L, "No arguments.\n"); - - -fprint(RESULT, L, - "\n-- Special characters need to be escaped\n" & - "> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n" - ); - -fprint(RESULT, L, "Special characters: \% \\ "" \n"); - - -fprint(RESULT, L, - "\n-- Various format specifiers interprete the same object differently\n" & - "> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" & - "> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" & - "> );\n" - ); - -fprint(RESULT, L, "Format specifiers: %r %d %b %q\n", - fo(Uns), fo(Uns), fo(Uns), fo(Uns) - ); - -fprint(RESULT, L, - "\n-- Format string can be shortened by using the iteration specifier\n" & - "> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" & - "> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" & - "> );\n" - ); - -fprint(RESULT, L, "Iteration specifier: %4{%r }\n", - fo(Uns), fo(SigPos), fo(SigNeg), fo(Std) - ); -fprint(RESULT, L, - "\n-------------------------------\n"& - "--Testing string manipulation--\n"& - "-------------------------------\n"); -fprint(RESULT, L, "--testing done using the string TempString : " & """ABC""" - & " & NUL & ""DEF""\n"); --- temp_string: string:="ABC"&NUL&"DEF" --- test for detecting NUL in string -fprint(RESULT, L, "\n--test for NUL ending in strings\n"); -fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n"); -fprint(RESULT, L, fo(TempString)); - --- direct inclusion of string in fprint should give whole string -fprint(RESULT, L, "\n--same without fo,so without NUL testing\n"); -fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n"); -fprint(RESULT, L, TempString & "\n"); - --- influence of given width - -fprint(RESULT, L, "\n--if there are less characters in the given string then" - & " in the width fo will\n"& - "-- pad the remaining with blanco's according to the given justification\n"); -fprint(RESULT, L, "\n--with specified width, justified right,using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n"); -fprint(RESULT, L, "%5s", fo(TempString)); -fprint(RESULT, L, "\n--with specified width, justified left, using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n"); -fprint(RESULT, L, "%-5s",fo(TempString)); -fprint(RESULT, L, "\n--with specified width without fo\n"); -fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n"); -fprint(RESULT, L, "%9s", TempString); -fprint(RESULT, L, "\n\n-- if the width is smaller then the number" & - " of characters in the string fprint\n" & - "-- will output the string with the minimum of characters needed\n"); -fprint(RESULT, L, "\n--with specified width,using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n"); -fprint(RESULT, L, "%2s",fo(TempString)); -fprint(RESULT, L, "\n--with specified width without fo\n"); -fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n"); -fprint(RESULT, L, "%4s", TempString); - - -fprint(RESULT, L, - "\n\n------------------------------------\n" & - "-- Support for bit-oriented types --\n" & - "------------------------------------\n" - ); - -fprint (RESULT, L, "\n-- Reasonable format\n" & - "> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Reasonable format: %9{%r }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint (RESULT, L, "\n-- Decimal format\n" & - "> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Decimal format: %9{%d }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint (RESULT, L, "\n-- Bit format\n" & - "> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Bit format: %9{%b }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint(RESULT, L, - "\n\n" & - "-- Alignment\n-- Template of the call: ( stands for the format specifier)\n" - ); - - -fprint(RESULT, L, "\n" & - "> fprint(RESULT, L, ""Bitvectors with : \%4{|}\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" & - - "> );\n" - ); - -fprint(RESULT, L, - "\n" & - "-- Results of the call with various format specifiers\n\n" - ); - -fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); - - - -fprint(RESULT, L, - "\n-------------------------------\n" & - "-- Support for integer types --\n" & - "-------------------------------\n" - ); - -fprint(RESULT, L, - "\n\n" & - "-- Template of the call: ( stands for the format specifier)\n" - ); - - -fprint(RESULT, L, "\n" & - "> fprint(RESULT, L, ""Integers with : \%4{|}\\n"",\n" & - "> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" & - - "> );\n" - ); - -fprint(RESULT, L, - "\n" & - "-- Results of the call with various format specifiers\n\n" - ); - - -fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); - - -fprint(RESULT, L, - "\n----------------------\n" & - "-- Support for time --\n" & - "----------------------\n" - ); - -fprint (RESULT, L, "-- For portability reasons, time is converted \n" & - "-- into an integer value (of nanoseconds)\n" - ); -fprint (RESULT, L, "> wait for 648 ns\n"); -fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n"); - -wait for 648 ns; - -fprint (RESULT, L, "The time is now %d ns\n", fo(now)); - - -fprint(RESULT, L, - "\n----------------------------------------\n" & - "-- Erroneous calls and error messages --\n" & - "----------------------------------------\n" - ); - -fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" & - "> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n" - ); - -fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std)); - -fprint(RESULT, L, "\n"); - -fprint(RESULT, L, "-- Unsupported format specifier\n" & - "> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " & - "fo(Uns), fo(Std), fo(Uns), fo(Std));\n" - ); - -fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std)); - -fprint(RESULT, L, "\n"); - -fprint(RESULT, L, - "\n----------------------------------------\n" & - "-- Things you wouldn't expect to work --\n" & - "----------------------------------------\n" - ); - -fprint(RESULT, L, "\n-- Nested iteration\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n"); -fprint(RESULT, L, "%3{<<%3{_END_}>>}\n"); - -wait; - -end process USAGE; - -end TB; - - +---- $Id: TB_PCK_FIO_1987.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + +library IEEE; +use IEEE.std_logic_1164.all; +-- signed/unsigned definition: use either std_logic_arith or numeric_std +-- use IEEE.std_logic_arith.all; -- the Synopsys one + use IEEE.numeric_std.all; + +use STD.TEXTIO.all; + +library EASICS_PACKAGES; +use EASICS_PACKAGES.PCK_FIO.all; + +entity TBE_PCK_FIO is + +end TBE_PCK_FIO; + +architecture TB of TBE_PCK_FIO is + +begin + +USAGE: process + + file RESULT: text is out "PCK_FIO.out"; + variable L: line; + variable Pointer: integer; + variable BoolTrue: boolean := TRUE; + variable BoolFalse: boolean := FALSE; + variable IntPos: integer := 5678; + variable BigIntPos: integer := 12345678; + variable IntNeg: integer := -8765; + variable BigIntNeg: integer := -87654321; + variable Uns: unsigned(6 downto 0) := unsigned'("1010010"); + variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10"); + variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010"); + variable SigPos: signed(6 downto 0) := signed'("0010010"); + variable SigNeg: signed(6 downto 0) := signed'("1010010"); + variable BitX: std_logic := 'X'; + variable Bit1: std_logic := '1'; + variable Bit0: std_logic := '0'; + + variable parameter_1: integer := 1234; + variable parameter_2: integer := 2345; + variable parameter_3: integer := 4567; + + constant TempString: string :="ABC" & NUL & "DEF"; +begin + +fprint(RESULT, L, + "PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" & + "-----------------------------------------\n\n" & + "This is the result of running the PCK_FIO testbench.\n" & + "This file should be compared with PCK_FIO.out.gold, which is\n" & + "the reference output. Any difference indicates a portability\n" & + "issue or a simulator non-compliance or bug.\n\n" + ); + + +fprint(RESULT, L, + "\n--------------------\n" & + "-- Basic features --\n" & + "--------------------\n\n" + ); + +fprint(RESULT, L, + "-- First some auxiliary declarations\n" + ); + +fprint(RESULT, L, + "> file RESULT: text is out ""PCK_FIO.out"";\n" & + "> variable L: line;\n" & + "> variable BoolTrue: boolean := TRUE;\n" & + "> variable BoolFalse: boolean := FALSE;\n" & + "> variable IntPos: integer := 5678;\n" & + "> variable BigIntPos: integer := 12345678;\n" & + "> variable IntNeg: integer := -8765;\n" & + "> variable BigIntNeg: integer := -87654321;\n" & + "> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" & + "> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" & + "> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" & + "> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" & + "> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" & + "> variable BitX: std_logic := 'X';\n" & + "> variable Bit1: std_logic := '1';\n" & + "> variable Bit0: std_logic := '0';\n" & + "> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n" +); + + +fprint(RESULT, L, + "\n\n-- fprint call with no arguments\n" & + "> fprint(RESULT, L, ""No arguments.\\n"");\n" + ); +fprint(RESULT, L, "No arguments.\n"); + + +fprint(RESULT, L, + "\n-- Special characters need to be escaped\n" & + "> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n" + ); + +fprint(RESULT, L, "Special characters: \% \\ "" \n"); + + +fprint(RESULT, L, + "\n-- Various format specifiers interprete the same object differently\n" & + "> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" & + "> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" & + "> );\n" + ); + +fprint(RESULT, L, "Format specifiers: %r %d %b %q\n", + fo(Uns), fo(Uns), fo(Uns), fo(Uns) + ); + +fprint(RESULT, L, + "\n-- Format string can be shortened by using the iteration specifier\n" & + "> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" & + "> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" & + "> );\n" + ); + +fprint(RESULT, L, "Iteration specifier: %4{%r }\n", + fo(Uns), fo(SigPos), fo(SigNeg), fo(Std) + ); +fprint(RESULT, L, + "\n-------------------------------\n"& + "--Testing string manipulation--\n"& + "-------------------------------\n"); +fprint(RESULT, L, "--testing done using the string TempString : " & """ABC""" + & " & NUL & ""DEF""\n"); +-- temp_string: string:="ABC"&NUL&"DEF" +-- test for detecting NUL in string +fprint(RESULT, L, "\n--test for NUL ending in strings\n"); +fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n"); +fprint(RESULT, L, fo(TempString)); + +-- direct inclusion of string in fprint should give whole string +fprint(RESULT, L, "\n--same without fo,so without NUL testing\n"); +fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n"); +fprint(RESULT, L, TempString & "\n"); + +-- influence of given width + +fprint(RESULT, L, "\n--if there are less characters in the given string then" + & " in the width fo will\n"& + "-- pad the remaining with blanco's according to the given justification\n"); +fprint(RESULT, L, "\n--with specified width, justified right,using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n"); +fprint(RESULT, L, "%5s", fo(TempString)); +fprint(RESULT, L, "\n--with specified width, justified left, using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n"); +fprint(RESULT, L, "%-5s",fo(TempString)); +fprint(RESULT, L, "\n--with specified width without fo\n"); +fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n"); +fprint(RESULT, L, "%9s", TempString); +fprint(RESULT, L, "\n\n-- if the width is smaller then the number" & + " of characters in the string fprint\n" & + "-- will output the string with the minimum of characters needed\n"); +fprint(RESULT, L, "\n--with specified width,using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n"); +fprint(RESULT, L, "%2s",fo(TempString)); +fprint(RESULT, L, "\n--with specified width without fo\n"); +fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n"); +fprint(RESULT, L, "%4s", TempString); + + +fprint(RESULT, L, + "\n\n------------------------------------\n" & + "-- Support for bit-oriented types --\n" & + "------------------------------------\n" + ); + +fprint (RESULT, L, "\n-- Reasonable format\n" & + "> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Reasonable format: %9{%r }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint (RESULT, L, "\n-- Decimal format\n" & + "> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Decimal format: %9{%d }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint (RESULT, L, "\n-- Bit format\n" & + "> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Bit format: %9{%b }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint(RESULT, L, + "\n\n" & + "-- Alignment\n-- Template of the call: ( stands for the format specifier)\n" + ); + + +fprint(RESULT, L, "\n" & + "> fprint(RESULT, L, ""Bitvectors with : \%4{|}\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" & + + "> );\n" + ); + +fprint(RESULT, L, + "\n" & + "-- Results of the call with various format specifiers\n\n" + ); + +fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); + + + +fprint(RESULT, L, + "\n-------------------------------\n" & + "-- Support for integer types --\n" & + "-------------------------------\n" + ); + +fprint(RESULT, L, + "\n\n" & + "-- Template of the call: ( stands for the format specifier)\n" + ); + + +fprint(RESULT, L, "\n" & + "> fprint(RESULT, L, ""Integers with : \%4{|}\\n"",\n" & + "> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" & + + "> );\n" + ); + +fprint(RESULT, L, + "\n" & + "-- Results of the call with various format specifiers\n\n" + ); + + +fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); + + +fprint(RESULT, L, + "\n----------------------\n" & + "-- Support for time --\n" & + "----------------------\n" + ); + +fprint (RESULT, L, "-- For portability reasons, time is converted \n" & + "-- into an integer value (of nanoseconds)\n" + ); +fprint (RESULT, L, "> wait for 648 ns\n"); +fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n"); + +wait for 648 ns; + +fprint (RESULT, L, "The time is now %d ns\n", fo(now)); + + +fprint(RESULT, L, + "\n----------------------------------------\n" & + "-- Erroneous calls and error messages --\n" & + "----------------------------------------\n" + ); + +fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" & + "> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n" + ); + +fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std)); + +fprint(RESULT, L, "\n"); + +fprint(RESULT, L, "-- Unsupported format specifier\n" & + "> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " & + "fo(Uns), fo(Std), fo(Uns), fo(Std));\n" + ); + +fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std)); + +fprint(RESULT, L, "\n"); + +fprint(RESULT, L, + "\n----------------------------------------\n" & + "-- Things you wouldn't expect to work --\n" & + "----------------------------------------\n" + ); + +fprint(RESULT, L, "\n-- Nested iteration\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n"); +fprint(RESULT, L, "%3{<<%3{_END_}>>}\n"); + +wait; + +end process USAGE; + +end TB; + + diff --git a/lib/PCK_FIO-2002.7/TB_PCK_FIO_1993.vhd b/lib/PCK_FIO-2002.7/TB_PCK_FIO_1993.vhd index 0386a11..17c27e3 100644 --- a/lib/PCK_FIO-2002.7/TB_PCK_FIO_1993.vhd +++ b/lib/PCK_FIO-2002.7/TB_PCK_FIO_1993.vhd @@ -1,536 +1,536 @@ ----- $Id: TB_PCK_FIO_1993.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $ ----- ----- PCK_FIO: a VHDL package for C-style formatted file output ----- Copyright (C) 1995, 2001 Easics NV ----- ----- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----- ----- For suggestions, bug reports, enhancement requests, and info about ----- our design services, you can contact us at the following address: ----- http://www.easics.com ----- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ----- tel.: +32 16 395 600 fax : +32 16 395 619 ----- e-mail: jand@easics.be (Jan Decaluwe) ----- - - -library IEEE; -use IEEE.std_logic_1164.all; --- signed/unsigned definition: use either std_logic_arith or numeric_std --- use IEEE.std_logic_arith.all; -- the Synopsys one -use IEEE.numeric_std.all; - -use STD.TEXTIO.all; - -library EASICS_PACKAGES; -use EASICS_PACKAGES.PCK_FIO.all; - -entity TBE_PCK_FIO is - -end TBE_PCK_FIO; - -architecture TB of TBE_PCK_FIO is - -begin - -USAGE: process - - file RESULT: text open write_mode is "PCK_FIO.out"; - variable L: line; - variable Pointer: integer; - variable BoolTrue: boolean := TRUE; - variable BoolFalse: boolean := FALSE; - variable IntPos: integer := 5678; - variable BigIntPos: integer := 12345678; - variable IntNeg: integer := -8765; - variable BigIntNeg: integer := -87654321; - variable Uns: unsigned(6 downto 0) := unsigned'("1010010"); - variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10"); - variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010"); - variable SigPos: signed(6 downto 0) := signed'("0010010"); - variable SigNeg: signed(6 downto 0) := signed'("1010010"); - variable BitX: std_logic := 'X'; - variable Bit1: std_logic := '1'; - variable Bit0: std_logic := '0'; - - variable parameter_1: integer := 1234; - variable parameter_2: integer := 2345; - variable parameter_3: integer := 4567; - - constant TempString: string :="ABC" & NUL & "DEF"; -begin - -fprint(RESULT, L, - "PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" & - "-----------------------------------------\n\n" & - "This is the result of running the PCK_FIO testbench.\n" & - "This file should be compared with PCK_FIO.out.gold, which is\n" & - "the reference output. Any difference indicates a portability\n" & - "issue or a simulator non-compliance or bug.\n\n" - ); - - -fprint(RESULT, L, - "\n--------------------\n" & - "-- Basic features --\n" & - "--------------------\n\n" - ); - -fprint(RESULT, L, - "-- First some auxiliary declarations\n" - ); - -fprint(RESULT, L, - "> file RESULT: text is out ""PCK_FIO.out"";\n" & - "> variable L: line;\n" & - "> variable BoolTrue: boolean := TRUE;\n" & - "> variable BoolFalse: boolean := FALSE;\n" & - "> variable IntPos: integer := 5678;\n" & - "> variable BigIntPos: integer := 12345678;\n" & - "> variable IntNeg: integer := -8765;\n" & - "> variable BigIntNeg: integer := -87654321;\n" & - "> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" & - "> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" & - "> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" & - "> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" & - "> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" & - "> variable BitX: std_logic := 'X';\n" & - "> variable Bit1: std_logic := '1';\n" & - "> variable Bit0: std_logic := '0';\n" & - "> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n" -); - - -fprint(RESULT, L, - "\n\n-- fprint call with no arguments\n" & - "> fprint(RESULT, L, ""No arguments.\\n"");\n" - ); -fprint(RESULT, L, "No arguments.\n"); - - -fprint(RESULT, L, - "\n-- Special characters need to be escaped\n" & - "> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n" - ); - -fprint(RESULT, L, "Special characters: \% \\ "" \n"); - - -fprint(RESULT, L, - "\n-- Various format specifiers interprete the same object differently\n" & - "> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" & - "> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" & - "> );\n" - ); - -fprint(RESULT, L, "Format specifiers: %r %d %b %q\n", - fo(Uns), fo(Uns), fo(Uns), fo(Uns) - ); - -fprint(RESULT, L, - "\n-- Format string can be shortened by using the iteration specifier\n" & - "> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" & - "> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" & - "> );\n" - ); - -fprint(RESULT, L, "Iteration specifier: %4{%r }\n", - fo(Uns), fo(SigPos), fo(SigNeg), fo(Std) - ); -fprint(RESULT, L, - "\n-------------------------------\n"& - "--Testing string manipulation--\n"& - "-------------------------------\n"); -fprint(RESULT, L, "--testing done using the string TempString : " & """ABC""" - & " & NUL & ""DEF""\n"); --- TempString: string:="ABC" & NUL & "DEF" --- test for detecting NUL in string -fprint(RESULT, L ,"\n--test for NUL ending in strings\n"); -fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n"); -fprint(RESULT, L, fo(TempString)); - --- direct inclusion of string in fprint should give whole string -fprint(RESULT, L, "\n--same without fo,so without NUL testing\n"); -fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n"); -fprint(RESULT, L, TempString & "\n"); - --- influence of given width - -fprint(RESULT, L, "\n--if there are less characters in the given string then in the width fo will\n"& - "-- pad the remaining with blanco's according to the given justification\n"); -fprint(RESULT, L, "\n--with specified width, justified right,using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n"); -fprint(RESULT, L, "%5s", fo(TempString)); -fprint(RESULT, L, "\n--with specified width, justified left, using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n"); -fprint(RESULT, L, "%-5s", fo(TempString)); -fprint(RESULT, L, "\n--with specified width without fo\n"); -fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n"); -fprint(RESULT, L, "%9s", TempString); -fprint(RESULT, L, "\n\n-- if the width is smaller then the number of characters in the string fprint\n"& - "-- will output the string with the minimum of characters needed\n"); -fprint(RESULT, L, "\n--with specified width,using fo\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n"); -fprint(RESULT, L, "%2s", fo(TempString)); -fprint(RESULT, L, "\n--with specified width without fo\n"); -fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n"); -fprint(RESULT, L, "%4s", TempString); - -fprint(RESULT, L, - "\n\n------------------------------------\n" & - "-- Support for bit-oriented types --\n" & - "------------------------------------\n" - ); - -fprint (RESULT, L, "\n-- Reasonable format\n" & - "> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Reasonable format: %9{%r }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint (RESULT, L, "\n-- Decimal format\n" & - "> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Decimal format: %9{%d }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint (RESULT, L, "\n-- Bit format\n" & - "> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & - "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & - "> );\n" - ); - - -fprint(RESULT, L, "Bit format: %9{%b }\n", - fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), - fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) - ); - -fprint(RESULT, L, - "\n\n" & - "-- Alignment\n-- Template of the call: ( stands for the format specifier)\n" - ); - - -fprint(RESULT, L, "\n" & - "> fprint(RESULT, L, ""Bitvectors with : \%4{|}\\n"",\n" & - "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" & - "> );\n" - ); - -fprint(RESULT, L, - "\n" & - "-- Results of the call with various format specifiers\n\n" - ); - -fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n", - fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) - ); -fprint(RESULT, L, "\n"); - - - -fprint(RESULT, L, - "\n-------------------------------\n" & - "-- Support for integer types --\n" & - "-------------------------------\n" - ); - -fprint(RESULT, L, - "\n\n" & - "-- Template of the call: ( stands for the format specifier)\n" - ); - - -fprint(RESULT, L, "\n" & - "> fprint(RESULT, L, ""Integers with : \%4{|}\\n"",\n" & - "> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" & - - "> );\n" - ); - -fprint(RESULT, L, - "\n" & - "-- Results of the call with various format specifiers\n\n" - ); - - -fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); -fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n", - fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) - ); -fprint(RESULT, L, "\n"); - - -fprint(RESULT, L, - "\n----------------------\n" & - "-- Support for time --\n" & - "----------------------\n" - ); - -fprint (RESULT, L, "-- For portability reasons, time is converted \n" & - "-- into an integer value (of nanoseconds)\n" - ); -fprint (RESULT, L, "> wait for 648 ns\n"); -fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n"); - -wait for 648 ns; - -fprint (RESULT, L, "The time is now %d ns\n", fo(now)); - - -fprint(RESULT, L, - "\n----------------------------------------\n" & - "-- Erroneous calls and error messages --\n" & - "----------------------------------------\n" - ); - -fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" & - "> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n" - ); - -fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std)); - -fprint(RESULT, L, "\n"); - -fprint(RESULT, L, "-- Unsupported format specifier\n" & - "> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " & - "fo(Uns), fo(Std), fo(Uns), fo(Std));\n" - ); - -fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std)); - -fprint(RESULT, L, "\n"); - -fprint(RESULT, L, - "\n----------------------------------------\n" & - "-- Things you wouldn't expect to work --\n" & - "----------------------------------------\n" - ); - -fprint(RESULT, L, "\n-- Nested iteration\n"); -fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n"); -fprint(RESULT, L, "%3{<<%3{_END_}>>}\n"); - -wait; - -end process USAGE; - -end TB; - - - - - - - - - - - +---- $Id: TB_PCK_FIO_1993.vhd,v 1.1 2008/08/23 08:20:28 Jens Exp $ +---- +---- PCK_FIO: a VHDL package for C-style formatted file output +---- Copyright (C) 1995, 2001 Easics NV +---- +---- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---- +---- For suggestions, bug reports, enhancement requests, and info about +---- our design services, you can contact us at the following address: +---- http://www.easics.com +---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium +---- tel.: +32 16 395 600 fax : +32 16 395 619 +---- e-mail: jand@easics.be (Jan Decaluwe) +---- + + +library IEEE; +use IEEE.std_logic_1164.all; +-- signed/unsigned definition: use either std_logic_arith or numeric_std +-- use IEEE.std_logic_arith.all; -- the Synopsys one +use IEEE.numeric_std.all; + +use STD.TEXTIO.all; + +library EASICS_PACKAGES; +use EASICS_PACKAGES.PCK_FIO.all; + +entity TBE_PCK_FIO is + +end TBE_PCK_FIO; + +architecture TB of TBE_PCK_FIO is + +begin + +USAGE: process + + file RESULT: text open write_mode is "PCK_FIO.out"; + variable L: line; + variable Pointer: integer; + variable BoolTrue: boolean := TRUE; + variable BoolFalse: boolean := FALSE; + variable IntPos: integer := 5678; + variable BigIntPos: integer := 12345678; + variable IntNeg: integer := -8765; + variable BigIntNeg: integer := -87654321; + variable Uns: unsigned(6 downto 0) := unsigned'("1010010"); + variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10"); + variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010"); + variable SigPos: signed(6 downto 0) := signed'("0010010"); + variable SigNeg: signed(6 downto 0) := signed'("1010010"); + variable BitX: std_logic := 'X'; + variable Bit1: std_logic := '1'; + variable Bit0: std_logic := '0'; + + variable parameter_1: integer := 1234; + variable parameter_2: integer := 2345; + variable parameter_3: integer := 4567; + + constant TempString: string :="ABC" & NUL & "DEF"; +begin + +fprint(RESULT, L, + "PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" & + "-----------------------------------------\n\n" & + "This is the result of running the PCK_FIO testbench.\n" & + "This file should be compared with PCK_FIO.out.gold, which is\n" & + "the reference output. Any difference indicates a portability\n" & + "issue or a simulator non-compliance or bug.\n\n" + ); + + +fprint(RESULT, L, + "\n--------------------\n" & + "-- Basic features --\n" & + "--------------------\n\n" + ); + +fprint(RESULT, L, + "-- First some auxiliary declarations\n" + ); + +fprint(RESULT, L, + "> file RESULT: text is out ""PCK_FIO.out"";\n" & + "> variable L: line;\n" & + "> variable BoolTrue: boolean := TRUE;\n" & + "> variable BoolFalse: boolean := FALSE;\n" & + "> variable IntPos: integer := 5678;\n" & + "> variable BigIntPos: integer := 12345678;\n" & + "> variable IntNeg: integer := -8765;\n" & + "> variable BigIntNeg: integer := -87654321;\n" & + "> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" & + "> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" & + "> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" & + "> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" & + "> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" & + "> variable BitX: std_logic := 'X';\n" & + "> variable Bit1: std_logic := '1';\n" & + "> variable Bit0: std_logic := '0';\n" & + "> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n" +); + + +fprint(RESULT, L, + "\n\n-- fprint call with no arguments\n" & + "> fprint(RESULT, L, ""No arguments.\\n"");\n" + ); +fprint(RESULT, L, "No arguments.\n"); + + +fprint(RESULT, L, + "\n-- Special characters need to be escaped\n" & + "> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n" + ); + +fprint(RESULT, L, "Special characters: \% \\ "" \n"); + + +fprint(RESULT, L, + "\n-- Various format specifiers interprete the same object differently\n" & + "> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" & + "> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" & + "> );\n" + ); + +fprint(RESULT, L, "Format specifiers: %r %d %b %q\n", + fo(Uns), fo(Uns), fo(Uns), fo(Uns) + ); + +fprint(RESULT, L, + "\n-- Format string can be shortened by using the iteration specifier\n" & + "> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" & + "> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" & + "> );\n" + ); + +fprint(RESULT, L, "Iteration specifier: %4{%r }\n", + fo(Uns), fo(SigPos), fo(SigNeg), fo(Std) + ); +fprint(RESULT, L, + "\n-------------------------------\n"& + "--Testing string manipulation--\n"& + "-------------------------------\n"); +fprint(RESULT, L, "--testing done using the string TempString : " & """ABC""" + & " & NUL & ""DEF""\n"); +-- TempString: string:="ABC" & NUL & "DEF" +-- test for detecting NUL in string +fprint(RESULT, L ,"\n--test for NUL ending in strings\n"); +fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n"); +fprint(RESULT, L, fo(TempString)); + +-- direct inclusion of string in fprint should give whole string +fprint(RESULT, L, "\n--same without fo,so without NUL testing\n"); +fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n"); +fprint(RESULT, L, TempString & "\n"); + +-- influence of given width + +fprint(RESULT, L, "\n--if there are less characters in the given string then in the width fo will\n"& + "-- pad the remaining with blanco's according to the given justification\n"); +fprint(RESULT, L, "\n--with specified width, justified right,using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n"); +fprint(RESULT, L, "%5s", fo(TempString)); +fprint(RESULT, L, "\n--with specified width, justified left, using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n"); +fprint(RESULT, L, "%-5s", fo(TempString)); +fprint(RESULT, L, "\n--with specified width without fo\n"); +fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n"); +fprint(RESULT, L, "%9s", TempString); +fprint(RESULT, L, "\n\n-- if the width is smaller then the number of characters in the string fprint\n"& + "-- will output the string with the minimum of characters needed\n"); +fprint(RESULT, L, "\n--with specified width,using fo\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n"); +fprint(RESULT, L, "%2s", fo(TempString)); +fprint(RESULT, L, "\n--with specified width without fo\n"); +fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n"); +fprint(RESULT, L, "%4s", TempString); + +fprint(RESULT, L, + "\n\n------------------------------------\n" & + "-- Support for bit-oriented types --\n" & + "------------------------------------\n" + ); + +fprint (RESULT, L, "\n-- Reasonable format\n" & + "> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Reasonable format: %9{%r }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint (RESULT, L, "\n-- Decimal format\n" & + "> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Decimal format: %9{%d }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint (RESULT, L, "\n-- Bit format\n" & + "> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" & + "> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" & + "> );\n" + ); + + +fprint(RESULT, L, "Bit format: %9{%b }\n", + fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk), + fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) + ); + +fprint(RESULT, L, + "\n\n" & + "-- Alignment\n-- Template of the call: ( stands for the format specifier)\n" + ); + + +fprint(RESULT, L, "\n" & + "> fprint(RESULT, L, ""Bitvectors with : \%4{|}\\n"",\n" & + "> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" & + "> );\n" + ); + +fprint(RESULT, L, + "\n" & + "-- Results of the call with various format specifiers\n\n" + ); + +fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n", + fo(Uns), fo(Std), fo(SigPos), fo(SigNeg) + ); +fprint(RESULT, L, "\n"); + + + +fprint(RESULT, L, + "\n-------------------------------\n" & + "-- Support for integer types --\n" & + "-------------------------------\n" + ); + +fprint(RESULT, L, + "\n\n" & + "-- Template of the call: ( stands for the format specifier)\n" + ); + + +fprint(RESULT, L, "\n" & + "> fprint(RESULT, L, ""Integers with : \%4{|}\\n"",\n" & + "> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" & + + "> );\n" + ); + +fprint(RESULT, L, + "\n" & + "-- Results of the call with various format specifiers\n\n" + ); + + +fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); +fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n", + fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg) + ); +fprint(RESULT, L, "\n"); + + +fprint(RESULT, L, + "\n----------------------\n" & + "-- Support for time --\n" & + "----------------------\n" + ); + +fprint (RESULT, L, "-- For portability reasons, time is converted \n" & + "-- into an integer value (of nanoseconds)\n" + ); +fprint (RESULT, L, "> wait for 648 ns\n"); +fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n"); + +wait for 648 ns; + +fprint (RESULT, L, "The time is now %d ns\n", fo(now)); + + +fprint(RESULT, L, + "\n----------------------------------------\n" & + "-- Erroneous calls and error messages --\n" & + "----------------------------------------\n" + ); + +fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" & + "> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n" + ); + +fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std)); + +fprint(RESULT, L, "\n"); + +fprint(RESULT, L, "-- Unsupported format specifier\n" & + "> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " & + "fo(Uns), fo(Std), fo(Uns), fo(Std));\n" + ); + +fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std)); + +fprint(RESULT, L, "\n"); + +fprint(RESULT, L, + "\n----------------------------------------\n" & + "-- Things you wouldn't expect to work --\n" & + "----------------------------------------\n" + ); + +fprint(RESULT, L, "\n-- Nested iteration\n"); +fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n"); +fprint(RESULT, L, "%3{<<%3{_END_}>>}\n"); + +wait; + +end process USAGE; + +end TB; + + + + + + + + + + + diff --git a/lib/ac97_ctrl/sim/tb_ac97_wb.fdo b/lib/ac97_ctrl/sim/tb_ac97_wb.fdo index bbdc249..4d52382 100644 --- a/lib/ac97_ctrl/sim/tb_ac97_wb.fdo +++ b/lib/ac97_ctrl/sim/tb_ac97_wb.fdo @@ -4,8 +4,8 @@ vlib work vcom -explicit -93 "../../FIFO/src/fifo_ctrl_pkg.vhd" vcom -explicit -93 "../../FIFO/src/fifo_sync_ctrl.vhd" -vcom -explicit -93 "../../misc/dpram_1w1r_dist.vhd" -vcom -explicit -93 "../../FIFO/src/fifo_sync_dist.vhd" +vcom -explicit -93 "../../misc/dpram_1w1r.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_sync.vhd" vcom -explicit -93 "../../misc/singleshot.vhd" vcom -explicit -93 "../src/core/ac_out.vhd" vcom -explicit -93 "../src/core/ac_in.vhd" diff --git a/lib/misc/async_port_wb.vhd b/lib/misc/async_port_wb.vhd index 854edd0..2b9e878 100644 --- a/lib/misc/async_port_wb.vhd +++ b/lib/misc/async_port_wb.vhd @@ -1,317 +1,317 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/async_port_wb.vhd,v 1.16 2010-02-09 09:56:37 Jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.async_types.all; - - ------------------------------------------------------------------ -entity async_port_wb is - Generic - ( - f_sysclk : real := 100.0; - addr_width : natural := 32; - data_width : natural := 32; - byte_sel_width : natural := 4; - async_timespec : async_timespec_t - ); - Port - ( - CLK_I : in STD_LOGIC; - RST_I : in STD_LOGIC; - CYC_I : in STD_LOGIC; - STB_I : in STD_LOGIC; - WE_I : in STD_LOGIC; - ACK_O : out STD_LOGIC; - SRDY_O : out STD_LOGIC; - MRDY_I : in STD_LOGIC; - SEL_I : in unsigned(3 downto 0); - ADDR_I : in unsigned(31 downto 0); - DAT_I : in unsigned(31 downto 0); - DAT_O : out unsigned(31 downto 0); - page_mode_en : in STD_LOGIC; - async_a : out unsigned(addr_width-1 downto 0); - async_d : inout unsigned(data_width-1 downto 0); - async_cs : out std_logic; - async_wr : out std_logic; - async_rd : out std_logic; - async_be : out unsigned(byte_sel_width-1 downto 0); - async_rst : out std_logic - ); -end async_port_wb; - -architecture Behavioral of async_port_wb is - - type async_t is record - cs : std_logic; - wr : std_logic; - rd : std_logic; - rst : std_logic; - drive_d : std_logic; - end record; - - type async_state_t is (start, reset, idle, leadin, pulse, leadout, release); - - signal s, sn : async_state_t; - signal as : async_t; - signal ack : std_logic; - signal cc_rst : std_logic; - signal cycle_cnt : natural range 0 to 31; - signal cycle_reload : natural range 0 to 31; - signal rdy : std_logic; - signal rdyo : std_logic; - signal en : std_logic; - signal is_idle : std_logic; - signal DAT_I_r : unsigned(data_width-1 downto 0); - signal SEL_I_r : unsigned(byte_sel_width-1 downto 0); - signal WE_I_r : std_logic; - signal ADDR_I_r : unsigned(addr_width-1 downto 0); - signal page_mode_en_r : std_logic; - signal do_page_read : std_logic; - - ------------------------------------------------------------------ - begin - - ASSERT to_cycles(async_timespec.T_pulse_rd, f_sysclk) > 0 report "Read pulse length must be greater than zero!" severity failure; - ASSERT to_cycles(async_timespec.T_pulse_wr, f_sysclk) > 0 report "Write pulse length must be greater than zero!" severity failure; - ASSERT (not async_timespec.can_page_rd OR (to_cycles(async_timespec.T_pulse_page_rd, f_sysclk) > 1)) report "Read page pulse length must be greater than one!" severity failure; - - SRDY_O <= CYC_I and rdyo; - en <= CYC_I and STB_I; - - do_page_read <= '1' when (async_timespec.can_page_rd and (WE_I = '0') and (WE_I_r = '0') and (ADDR_I(addr_width-1 downto async_timespec.nbits_page_rd) = ADDR_I_r(addr_width-1 downto async_timespec.nbits_page_rd))) else '0'; - - proc_cycle_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if cc_rst = '1' then - cycle_cnt <= cycle_reload; - elsif cycle_cnt /= 0 then - cycle_cnt <= cycle_cnt - 1; - end if; - end if; - end process; - - ------------------------------------------------------------------ - proc_state_next: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - s <= start; - else - s <= sn; - end if; - end if; - end process; - - proc_state: - process(s, cycle_cnt, en, WE_I, WE_I_r, do_page_read) - begin - - cycle_reload <= to_cycles(async_timespec.T_pulse_rst, f_sysclk); - cc_rst <= '0'; - as.rst <= '0'; - as.cs <= '0'; - as.wr <= '0'; - as.rd <= '0'; - as.drive_d <= '0'; - ack <= '0'; - rdy <= '0'; - is_idle <= '0'; - - sn <= s; - case s is - - when start => - cc_rst <= '1'; - sn <= reset; - when reset => - as.rst <= '1'; - if cycle_cnt = 0 then - sn <= idle; - end if; - when idle => - rdy <= '1'; - is_idle <= '1'; - if en = '1' then - as.cs <= '1'; - cc_rst <= '1'; - if to_cycles(async_timespec.T_leadin, f_sysclk) = 0 then - sn <= pulse; - if WE_I = '1' then - cycle_reload <= 0; - sn <= leadin; -- always lead-in for writes - else - cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk) - 1; - as.rd <= '1'; - end if; - else - cycle_reload <= to_cycles(async_timespec.T_leadin, f_sysclk) - 1; - sn <= leadin; - end if; - end if; - - when leadin => - as.cs <= '1'; - as.rd <= not WE_I_r; - as.drive_d <= WE_I_r; - as.wr <= WE_I_r; - if cycle_cnt = 0 then - cc_rst <= '1'; - sn <= pulse; - if WE_I_r = '1' then - cycle_reload <= to_cycles(async_timespec.T_pulse_wr, f_sysclk) - 1; - else - cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk) - 1; - end if; - end if; - - when pulse => - as.cs <= '1'; - as.rd <= not WE_I_r; - as.drive_d <= WE_I_r; - as.wr <= WE_I_r; - if cycle_cnt = 0 then - as.wr <= '0'; - cc_rst <= '1'; - ack <= not WE_I_r; - rdy <= do_page_read; - if en = '1' and do_page_read = '1' then - cycle_reload <= to_cycles(async_timespec.T_pulse_page_rd, f_sysclk) - 1; - sn <= pulse; - elsif to_cycles(async_timespec.T_leadout, f_sysclk) = 0 then - if to_cycles(async_timespec.T_release, f_sysclk) = 0 then - sn <= idle; - else - cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk) - 1; - sn <= release; - end if; - else - cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk) - 1; - sn <= leadout; - end if; - end if; - - when leadout => - as.cs <= '1'; - as.drive_d <= WE_I_r; - if cycle_cnt = 0 then - cc_rst <= '1'; - if to_cycles(async_timespec.T_release, f_sysclk) = 0 then - sn <= idle; - else - cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk) - 1; - sn <= release; - end if; - end if; - - when release => - if cycle_cnt = 0 then - sn <= idle; - end if; - - when others => - sn <= idle; - - end case; - end process; - - ------------------------------------------------------------------ - output_ctrl: - process(CLK_I) - begin - if rising_edge(CLK_I) then - async_cs <= (not async_timespec.pol_cs) xor as.cs; - async_wr <= (not async_timespec.pol_we) xor as.wr; - async_rd <= (not async_timespec.pol_oe) xor as.rd; - async_rst <= (not async_timespec.pol_rst) xor as.rst; - end if; - end process; - - ------------------------------------------------------------------ - din_register: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if as.rd = '1' then - DAT_O(data_width-1 downto 0) <= async_d; - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_addr: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - async_a <= (others => '0'); - SEL_I_r <= (others => '0'); - elsif en = '1' and rdy = '1' then - async_a <= ADDR_I(addr_width-1 downto 0); - async_be <= (byte_sel_width-1 downto 0 => not async_timespec.pol_be) xor ((byte_sel_width-1 downto 0 => as.cs) and SEL_I(byte_sel_width-1 downto 0)); - SEL_I_r <= SEL_I(byte_sel_width-1 downto 0); - if is_idle = '1' then - ADDR_I_r <= ADDR_I(addr_width-1 downto 0); - end if; - end if; - end if; - end process; - - ------------------------------------------------------------------ - data_register: - process(CLK_I) - begin - if rising_edge(CLK_I) then - page_mode_en_r <= page_mode_en; - if en = '1' and rdy = '1' then - DAT_I_r <= DAT_I(data_width-1 downto 0); - WE_I_r <= WE_I; - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_SRDY: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - rdyo <= '1'; - elsif en = '1' then - rdyo <= rdy and not rdyo; - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_ACK: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - ACK_O <= '0'; - else - ACK_O <= ack; - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_data: - process(CLK_I) - begin - if rising_edge(CLK_I) then - async_d <= (others => 'Z'); - if as.drive_d = '1' then - async_d <= DAT_I_r; - end if; - end if; - end process; - - ------------------------------------------------------------------ - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/async_port_wb.vhd,v 1.16 2010/02/09 09:56:37 Jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.async_types.all; + + ------------------------------------------------------------------ +entity async_port_wb is + Generic + ( + f_sysclk : real := 100.0; + addr_width : natural := 32; + data_width : natural := 32; + byte_sel_width : natural := 4; + async_timespec : async_timespec_t + ); + Port + ( + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + page_mode_en : in STD_LOGIC; + async_a : out unsigned(addr_width-1 downto 0); + async_d : inout unsigned(data_width-1 downto 0); + async_cs : out std_logic; + async_wr : out std_logic; + async_rd : out std_logic; + async_be : out unsigned(byte_sel_width-1 downto 0); + async_rst : out std_logic + ); +end async_port_wb; + +architecture Behavioral of async_port_wb is + + type async_t is record + cs : std_logic; + wr : std_logic; + rd : std_logic; + rst : std_logic; + drive_d : std_logic; + end record; + + type async_state_t is (start, reset, idle, leadin, pulse, leadout, release); + + signal s, sn : async_state_t; + signal as : async_t; + signal ack : std_logic; + signal cc_rst : std_logic; + signal cycle_cnt : natural range 0 to 31; + signal cycle_reload : natural range 0 to 31; + signal rdy : std_logic; + signal rdyo : std_logic; + signal en : std_logic; + signal is_idle : std_logic; + signal DAT_I_r : unsigned(data_width-1 downto 0); + signal SEL_I_r : unsigned(byte_sel_width-1 downto 0); + signal WE_I_r : std_logic; + signal ADDR_I_r : unsigned(addr_width-1 downto 0); + signal page_mode_en_r : std_logic; + signal do_page_read : std_logic; + + ------------------------------------------------------------------ + begin + + ASSERT to_cycles(async_timespec.T_pulse_rd, f_sysclk) > 0 report "Read pulse length must be greater than zero!" severity failure; + ASSERT to_cycles(async_timespec.T_pulse_wr, f_sysclk) > 0 report "Write pulse length must be greater than zero!" severity failure; + ASSERT (not async_timespec.can_page_rd OR (to_cycles(async_timespec.T_pulse_page_rd, f_sysclk) > 1)) report "Read page pulse length must be greater than one!" severity failure; + + SRDY_O <= CYC_I and rdyo; + en <= CYC_I and STB_I; + + do_page_read <= '1' when (async_timespec.can_page_rd and (WE_I = '0') and (WE_I_r = '0') and (ADDR_I(addr_width-1 downto async_timespec.nbits_page_rd) = ADDR_I_r(addr_width-1 downto async_timespec.nbits_page_rd))) else '0'; + + proc_cycle_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if cc_rst = '1' then + cycle_cnt <= cycle_reload; + elsif cycle_cnt /= 0 then + cycle_cnt <= cycle_cnt - 1; + end if; + end if; + end process; + + ------------------------------------------------------------------ + proc_state_next: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + s <= start; + else + s <= sn; + end if; + end if; + end process; + + proc_state: + process(s, cycle_cnt, en, WE_I, WE_I_r, do_page_read) + begin + + cycle_reload <= to_cycles(async_timespec.T_pulse_rst, f_sysclk); + cc_rst <= '0'; + as.rst <= '0'; + as.cs <= '0'; + as.wr <= '0'; + as.rd <= '0'; + as.drive_d <= '0'; + ack <= '0'; + rdy <= '0'; + is_idle <= '0'; + + sn <= s; + case s is + + when start => + cc_rst <= '1'; + sn <= reset; + when reset => + as.rst <= '1'; + if cycle_cnt = 0 then + sn <= idle; + end if; + when idle => + rdy <= '1'; + is_idle <= '1'; + if en = '1' then + as.cs <= '1'; + cc_rst <= '1'; + if to_cycles(async_timespec.T_leadin, f_sysclk) = 0 then + sn <= pulse; + if WE_I = '1' then + cycle_reload <= 0; + sn <= leadin; -- always lead-in for writes + else + cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk) - 1; + as.rd <= '1'; + end if; + else + cycle_reload <= to_cycles(async_timespec.T_leadin, f_sysclk) - 1; + sn <= leadin; + end if; + end if; + + when leadin => + as.cs <= '1'; + as.rd <= not WE_I_r; + as.drive_d <= WE_I_r; + as.wr <= WE_I_r; + if cycle_cnt = 0 then + cc_rst <= '1'; + sn <= pulse; + if WE_I_r = '1' then + cycle_reload <= to_cycles(async_timespec.T_pulse_wr, f_sysclk) - 1; + else + cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk) - 1; + end if; + end if; + + when pulse => + as.cs <= '1'; + as.rd <= not WE_I_r; + as.drive_d <= WE_I_r; + as.wr <= WE_I_r; + if cycle_cnt = 0 then + as.wr <= '0'; + cc_rst <= '1'; + ack <= not WE_I_r; + rdy <= do_page_read; + if en = '1' and do_page_read = '1' then + cycle_reload <= to_cycles(async_timespec.T_pulse_page_rd, f_sysclk) - 1; + sn <= pulse; + elsif to_cycles(async_timespec.T_leadout, f_sysclk) = 0 then + if to_cycles(async_timespec.T_release, f_sysclk) = 0 then + sn <= idle; + else + cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk) - 1; + sn <= release; + end if; + else + cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk) - 1; + sn <= leadout; + end if; + end if; + + when leadout => + as.cs <= '1'; + as.drive_d <= WE_I_r; + if cycle_cnt = 0 then + cc_rst <= '1'; + if to_cycles(async_timespec.T_release, f_sysclk) = 0 then + sn <= idle; + else + cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk) - 1; + sn <= release; + end if; + end if; + + when release => + if cycle_cnt = 0 then + sn <= idle; + end if; + + when others => + sn <= idle; + + end case; + end process; + + ------------------------------------------------------------------ + output_ctrl: + process(CLK_I) + begin + if rising_edge(CLK_I) then + async_cs <= (not async_timespec.pol_cs) xor as.cs; + async_wr <= (not async_timespec.pol_we) xor as.wr; + async_rd <= (not async_timespec.pol_oe) xor as.rd; + async_rst <= (not async_timespec.pol_rst) xor as.rst; + end if; + end process; + + ------------------------------------------------------------------ + din_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if as.rd = '1' then + DAT_O(data_width-1 downto 0) <= async_d; + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_addr: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + async_a <= (others => '0'); + SEL_I_r <= (others => '0'); + elsif en = '1' and rdy = '1' then + async_a <= ADDR_I(addr_width-1 downto 0); + async_be <= (byte_sel_width-1 downto 0 => not async_timespec.pol_be) xor ((byte_sel_width-1 downto 0 => as.cs) and SEL_I(byte_sel_width-1 downto 0)); + SEL_I_r <= SEL_I(byte_sel_width-1 downto 0); + if is_idle = '1' then + ADDR_I_r <= ADDR_I(addr_width-1 downto 0); + end if; + end if; + end if; + end process; + + ------------------------------------------------------------------ + data_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + page_mode_en_r <= page_mode_en; + if en = '1' and rdy = '1' then + DAT_I_r <= DAT_I(data_width-1 downto 0); + WE_I_r <= WE_I; + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_SRDY: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + rdyo <= '1'; + elsif en = '1' then + rdyo <= rdy and not rdyo; + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_ACK: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + ACK_O <= '0'; + else + ACK_O <= ack; + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_data: + process(CLK_I) + begin + if rising_edge(CLK_I) then + async_d <= (others => 'Z'); + if as.drive_d = '1' then + async_d <= DAT_I_r; + end if; + end if; + end process; + + ------------------------------------------------------------------ + +end Behavioral; diff --git a/lib/misc/bbfifo.vhd b/lib/misc/bbfifo.vhd index aa8799f..4c7895f 100644 --- a/lib/misc/bbfifo.vhd +++ b/lib/misc/bbfifo.vhd @@ -1,123 +1,123 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/bbfifo.vhd,v 1.1 2008-10-20 19:26:01 Jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity bbfifo is - Generic - ( - depth : integer := 2; - data_width : integer := 8 - ); - Port - ( - rst : in STD_LOGIC; - clk : in STD_LOGIC; - re : in STD_LOGIC; - we : in STD_LOGIC; - ready : out STD_LOGIC; - avail : out STD_LOGIC; - din : in unsigned(data_width-1 downto 0); - dout : out unsigned(data_width-1 downto 0) - ); -end bbfifo; - -architecture Behavioral of bbfifo is - - type bucket_array_t is array (0 to depth) of unsigned(data_width-1 downto 0); - signal req : unsigned(0 to depth); - signal rdy : unsigned(1 to depth+1); - signal bucket_array : bucket_array_t; - signal ce_in : unsigned(1 to depth); - signal ce_out : unsigned(1 to depth); - -begin - - req(0) <= we; - rdy(depth+1) <= re; - ready <= '1' when req(0 to depth-1) /= (0 to depth-1 => '1') else '0'; - avail <= req(depth); - bucket_array(0) <= din; - dout <= bucket_array(depth); - -gen_ce: - for i in 1 to depth generate - begin - process (rdy, req) - begin - ce_in(i) <= not req(i) and req(i-1); - end process; - end generate; - -gen_rdy: - for i in 1 to depth generate - begin - process (clk) - begin - if rising_edge(clk) then - if rst = '1' then - rdy(i) <= '1'; - elsif req(i-1) = '1' then - rdy(i) <= rdy(i+1); - end if; - end if; - end process; - end generate; - -gen_req: - for i in 1 to depth generate - begin - process (clk) - begin - if rising_edge(clk) then - if rst = '1' then - req(i) <= '0'; - elsif rdy(i+1) = '1' then - req(i) <= req(i-1); - end if; - end if; - end process; - end generate; - -gen_data: - for i in 1 to depth generate - begin - process (clk) - begin - if rising_edge(clk) then - if rst = '1' then - bucket_array(i) <= (others => '0'); - elsif req(i-1) = '1' then - bucket_array(i) <= bucket_array(i-1); - end if; - end if; - end process; - end generate; - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/bbfifo.vhd,v 1.1 2008/10/20 19:26:01 Jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity bbfifo is + Generic + ( + depth : integer := 2; + data_width : integer := 8 + ); + Port + ( + rst : in STD_LOGIC; + clk : in STD_LOGIC; + re : in STD_LOGIC; + we : in STD_LOGIC; + ready : out STD_LOGIC; + avail : out STD_LOGIC; + din : in unsigned(data_width-1 downto 0); + dout : out unsigned(data_width-1 downto 0) + ); +end bbfifo; + +architecture Behavioral of bbfifo is + + type bucket_array_t is array (0 to depth) of unsigned(data_width-1 downto 0); + signal req : unsigned(0 to depth); + signal rdy : unsigned(1 to depth+1); + signal bucket_array : bucket_array_t; + signal ce_in : unsigned(1 to depth); + signal ce_out : unsigned(1 to depth); + +begin + + req(0) <= we; + rdy(depth+1) <= re; + ready <= '1' when req(0 to depth-1) /= (0 to depth-1 => '1') else '0'; + avail <= req(depth); + bucket_array(0) <= din; + dout <= bucket_array(depth); + +gen_ce: + for i in 1 to depth generate + begin + process (rdy, req) + begin + ce_in(i) <= not req(i) and req(i-1); + end process; + end generate; + +gen_rdy: + for i in 1 to depth generate + begin + process (clk) + begin + if rising_edge(clk) then + if rst = '1' then + rdy(i) <= '1'; + elsif req(i-1) = '1' then + rdy(i) <= rdy(i+1); + end if; + end if; + end process; + end generate; + +gen_req: + for i in 1 to depth generate + begin + process (clk) + begin + if rising_edge(clk) then + if rst = '1' then + req(i) <= '0'; + elsif rdy(i+1) = '1' then + req(i) <= req(i-1); + end if; + end if; + end process; + end generate; + +gen_data: + for i in 1 to depth generate + begin + process (clk) + begin + if rising_edge(clk) then + if rst = '1' then + bucket_array(i) <= (others => '0'); + elsif req(i-1) = '1' then + bucket_array(i) <= bucket_array(i-1); + end if; + end if; + end process; + end generate; + +end Behavioral; + diff --git a/lib/misc/debounce.vhd b/lib/misc/debounce.vhd index 79317a5..1e04db2 100644 --- a/lib/misc/debounce.vhd +++ b/lib/misc/debounce.vhd @@ -1,91 +1,91 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 19:34:24 10/23/05 --- Design Name: --- Module Name: debounce - Behavioral --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/debounce.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - -entity debounce is - Generic ( ncyc_latency : integer := 100); - Port ( rst : in std_logic; - clk : in std_logic; - input : in std_logic; - output : out std_logic); -end debounce; - -architecture Behavioral of debounce is - -type debounce_state_t is (init_st, wait_st, rel_st); -signal debounce_cs : debounce_state_t; -signal debounce_ns : debounce_state_t; -signal count : integer range 0 to ncyc_latency; -signal input_last : std_logic; - -begin - - debounce_clk: process(rst, clk, debounce_ns, debounce_cs, input) - begin - if (rst = '1') then - count <= 0; - output <= input; - input_last <= input; - else - if rising_edge(clk) then - debounce_cs <= debounce_ns; - if (debounce_cs = wait_st) then - if (count /= 0) then - count <= count - 1; - end if; - else - count <= ncyc_latency; - if (debounce_cs = rel_st) then - output <= input; - input_last <= input; - end if; - end if; - end if; - end if; - end process; - - debounce_in: process(rst, clk, input, input_last, debounce_cs, count) - begin - debounce_ns <= debounce_cs; - case debounce_cs is - when init_st => - if (input /= input_last) then - debounce_ns <= wait_st; - end if; - when wait_st => - if (count = 0) then - debounce_ns <= rel_st; - end if; - when others => - debounce_ns <= init_st; - end case; - end process; - -end Behavioral; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 19:34:24 10/23/05 +-- Design Name: +-- Module Name: debounce - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/debounce.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity debounce is + Generic ( ncyc_latency : integer := 100); + Port ( rst : in std_logic; + clk : in std_logic; + input : in std_logic; + output : out std_logic); +end debounce; + +architecture Behavioral of debounce is + +type debounce_state_t is (init_st, wait_st, rel_st); +signal debounce_cs : debounce_state_t; +signal debounce_ns : debounce_state_t; +signal count : integer range 0 to ncyc_latency; +signal input_last : std_logic; + +begin + + debounce_clk: process(rst, clk, debounce_ns, debounce_cs, input) + begin + if (rst = '1') then + count <= 0; + output <= input; + input_last <= input; + else + if rising_edge(clk) then + debounce_cs <= debounce_ns; + if (debounce_cs = wait_st) then + if (count /= 0) then + count <= count - 1; + end if; + else + count <= ncyc_latency; + if (debounce_cs = rel_st) then + output <= input; + input_last <= input; + end if; + end if; + end if; + end if; + end process; + + debounce_in: process(rst, clk, input, input_last, debounce_cs, count) + begin + debounce_ns <= debounce_cs; + case debounce_cs is + when init_st => + if (input /= input_last) then + debounce_ns <= wait_st; + end if; + when wait_st => + if (count = 0) then + debounce_ns <= rel_st; + end if; + when others => + debounce_ns <= init_st; + end case; + end process; + +end Behavioral; diff --git a/lib/misc/debounce2.vhd b/lib/misc/debounce2.vhd index 206a61c..ce5374a 100644 --- a/lib/misc/debounce2.vhd +++ b/lib/misc/debounce2.vhd @@ -1,142 +1,142 @@ -------------------------------------------------- --- Signal Debouncer --- Jeff Bazinet --- February 14, 2002 ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/debounce2.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ - - -library ieee; -use ieee.std_logic_1164.all; -library lpm; -use lpm.lpm_components.lpm_counter; - - -entity debounce is - generic(BUFFER_WIDTH: positive:= 30; - CLOCK_DIV: positive:= 15 - ); - port( clock: in std_logic; - reset: in std_logic; - signal_in: in std_logic; - signal_out: out std_logic - ); -end entity debounce; - - -architecture rtl of debounce is - - --------------------------------------------------------------- - -- SIGNAL DECLARATION - --------------------------------------------------------------- - - -- General - signal reset_n: std_logic; - - -- SLOW CLOCK GENERATION - signal clock_reg: std_logic_vector(CLOCK_DIV-1 downto 0); - signal clock_reg_high: std_logic_vector(CLOCK_DIV-1 downto 1); - signal clock_slow: std_logic; - signal clock_slow_wire: std_logic; - - -- DATA BUFFER FILL - signal counter_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); - signal data_buffer_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); - - -- CHECK FOR DEBOUNCE STABILITY - signal stable: std_logic; - signal stable_old: std_logic; - signal stable_state_reg:std_logic_vector(BUFFER_WIDTH-1 downto 0); - - -- PUSH BUTTON ENABLE - signal button_pushed: std_logic; - - begin - - --------------------------------------------------------------- - -- SLOW CLOCK GENERATION - --------------------------------------------------------------- - - COUNTER_1: lpm_counter - generic map (lpm_width => CLOCK_DIV) - port map ( - clock => clock, - sclr => reset_n, - cout => clock_slow_wire - ); - - process (clock) is - begin - - clock_slow <= clock_slow_wire; - - end process; - - --------------------------------------------------------------- - -- DATA BUFFER FILL - --------------------------------------------------------------- - - process (clock) is - begin - - if (reset = '0') then - -- Initialization - data_buffer_reg <= (others => '1'); - elsif rising_edge(clock_slow) then - data_buffer_reg <= data_buffer_reg(BUFFER_WIDTH-2 downto 0) & signal_in; - end if; - - end process; - - --------------------------------------------------------------- - -- CHECK FOR DEBOUNCE STABILITY - --------------------------------------------------------------- - - process (clock) is - begin - - if (reset = '0') then - -- Initialization - stable <= '0'; - stable_old <= '0'; - stable_state_reg <= (others => '0'); - elsif rising_edge(clock) then - if (data_buffer_reg = stable_state_reg) then - stable <= '1'; - stable_state_reg <= (others => '0'); - else - stable <= '0'; - end if; - stable_old <= stable; - end if; - - end process; - - --------------------------------------------------------------- - -- PUSH BUTTON ENABLE - --------------------------------------------------------------- - - process (clock) is - begin - - if (reset = '0') then - -- Initialization - button_pushed <= '0'; - elsif rising_edge(clock) then - if (stable_old = '0' and stable = '1') then - button_pushed <= '1'; - else - button_pushed <= '0'; - end if; - end if; - - end process; - - --------------------------------------------------------------- - --------------------------------------------------------------- - - signal_out <= button_pushed; - reset_n <= not reset; - -end rtl; +------------------------------------------------- +-- Signal Debouncer +-- Jeff Bazinet +-- February 14, 2002 +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/debounce2.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +library lpm; +use lpm.lpm_components.lpm_counter; + + +entity debounce is + generic(BUFFER_WIDTH: positive:= 30; + CLOCK_DIV: positive:= 15 + ); + port( clock: in std_logic; + reset: in std_logic; + signal_in: in std_logic; + signal_out: out std_logic + ); +end entity debounce; + + +architecture rtl of debounce is + + --------------------------------------------------------------- + -- SIGNAL DECLARATION + --------------------------------------------------------------- + + -- General + signal reset_n: std_logic; + + -- SLOW CLOCK GENERATION + signal clock_reg: std_logic_vector(CLOCK_DIV-1 downto 0); + signal clock_reg_high: std_logic_vector(CLOCK_DIV-1 downto 1); + signal clock_slow: std_logic; + signal clock_slow_wire: std_logic; + + -- DATA BUFFER FILL + signal counter_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); + signal data_buffer_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); + + -- CHECK FOR DEBOUNCE STABILITY + signal stable: std_logic; + signal stable_old: std_logic; + signal stable_state_reg:std_logic_vector(BUFFER_WIDTH-1 downto 0); + + -- PUSH BUTTON ENABLE + signal button_pushed: std_logic; + + begin + + --------------------------------------------------------------- + -- SLOW CLOCK GENERATION + --------------------------------------------------------------- + + COUNTER_1: lpm_counter + generic map (lpm_width => CLOCK_DIV) + port map ( + clock => clock, + sclr => reset_n, + cout => clock_slow_wire + ); + + process (clock) is + begin + + clock_slow <= clock_slow_wire; + + end process; + + --------------------------------------------------------------- + -- DATA BUFFER FILL + --------------------------------------------------------------- + + process (clock) is + begin + + if (reset = '0') then + -- Initialization + data_buffer_reg <= (others => '1'); + elsif rising_edge(clock_slow) then + data_buffer_reg <= data_buffer_reg(BUFFER_WIDTH-2 downto 0) & signal_in; + end if; + + end process; + + --------------------------------------------------------------- + -- CHECK FOR DEBOUNCE STABILITY + --------------------------------------------------------------- + + process (clock) is + begin + + if (reset = '0') then + -- Initialization + stable <= '0'; + stable_old <= '0'; + stable_state_reg <= (others => '0'); + elsif rising_edge(clock) then + if (data_buffer_reg = stable_state_reg) then + stable <= '1'; + stable_state_reg <= (others => '0'); + else + stable <= '0'; + end if; + stable_old <= stable; + end if; + + end process; + + --------------------------------------------------------------- + -- PUSH BUTTON ENABLE + --------------------------------------------------------------- + + process (clock) is + begin + + if (reset = '0') then + -- Initialization + button_pushed <= '0'; + elsif rising_edge(clock) then + if (stable_old = '0' and stable = '1') then + button_pushed <= '1'; + else + button_pushed <= '0'; + end if; + end if; + + end process; + + --------------------------------------------------------------- + --------------------------------------------------------------- + + signal_out <= button_pushed; + reset_n <= not reset; + +end rtl; diff --git a/lib/misc/dpram_1w1r.vhd b/lib/misc/dpram_1w1r.vhd index dee0972..9b3772b 100644 --- a/lib/misc/dpram_1w1r.vhd +++ b/lib/misc/dpram_1w1r.vhd @@ -1,79 +1,79 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clka : in STD_LOGIC; - clkb : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r; - -architecture Behavioral of dpram_1w1r is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - -process (clka) -begin -if clka'event and clka = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clkb) -begin -if clkb'event and clkb = '1' then - if en_b = '1' then - dout_b <= RAM(to_integer(addr_b)); - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clka : in STD_LOGIC; + clkb : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r; + +architecture Behavioral of dpram_1w1r is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + +process (clka) +begin +if clka'event and clka = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clkb) +begin +if clkb'event and clkb = '1' then + if en_b = '1' then + dout_b <= RAM(to_integer(addr_b)); + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/misc/dpram_1w1r1c_sim.vhd b/lib/misc/dpram_1w1r1c_sim.vhd index 692e773..661ce00 100644 --- a/lib/misc/dpram_1w1r1c_sim.vhd +++ b/lib/misc/dpram_1w1r1c_sim.vhd @@ -1,77 +1,77 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r1c_sim.vhd,v 1.1 2013-02-07 14:15:37 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r1c; - -architecture Behavioral of dpram_1w1r1c is - - signal addr_b_r : unsigned (addr_width-1 downto 0); - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - -process (clk) -begin -if clk'event and clk = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - -dout_b <= RAM(to_integer(addr_b_r)); - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r1c_sim.vhd,v 1.1 2013/02/07 14:15:37 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r1c; + +architecture Behavioral of dpram_1w1r1c is + + signal addr_b_r : unsigned (addr_width-1 downto 0); + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + +process (clk) +begin +if clk'event and clk = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + +dout_b <= RAM(to_integer(addr_b_r)); + + +end Behavioral; + diff --git a/lib/misc/dpram_1w1r1c_xil.vhd b/lib/misc/dpram_1w1r1c_xil.vhd index b47843e..aaaca69 100644 --- a/lib/misc/dpram_1w1r1c_xil.vhd +++ b/lib/misc/dpram_1w1r1c_xil.vhd @@ -1,77 +1,77 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r1c_xil.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r1c; - -architecture Behavioral of dpram_1w1r1c is - - signal addr_b_r : unsigned (addr_width-1 downto 0); - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - -process (clk) -begin -if clk'event and clk = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - -dout_b <= RAM(to_integer(addr_b_r)); - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r1c_xil.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r1c; + +architecture Behavioral of dpram_1w1r1c is + + signal addr_b_r : unsigned (addr_width-1 downto 0); + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + +process (clk) +begin +if clk'event and clk = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + +dout_b <= RAM(to_integer(addr_b_r)); + + +end Behavioral; + diff --git a/lib/misc/dpram_1w1r2c_sim.vhd b/lib/misc/dpram_1w1r2c_sim.vhd index dbcfb2d..4c3a043 100644 --- a/lib/misc/dpram_1w1r2c_sim.vhd +++ b/lib/misc/dpram_1w1r2c_sim.vhd @@ -1,82 +1,82 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r2c_sim.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c; - -architecture Behavioral of dpram_1w1r2c is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - signal addr_b_r : unsigned (addr_width-1 downto 0); - -begin - - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r2c_sim.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c; + +architecture Behavioral of dpram_1w1r2c is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + signal addr_b_r : unsigned (addr_width-1 downto 0); + +begin + + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/misc/dpram_1w1r2c_xil.vhd b/lib/misc/dpram_1w1r2c_xil.vhd index 0ed9be8..0f19220 100644 --- a/lib/misc/dpram_1w1r2c_xil.vhd +++ b/lib/misc/dpram_1w1r2c_xil.vhd @@ -1,82 +1,82 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r2c_xil.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c; - -architecture Behavioral of dpram_1w1r2c is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - signal addr_b_r : unsigned (addr_width-1 downto 0); - -begin - - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r2c_xil.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c; + +architecture Behavioral of dpram_1w1r2c is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + signal addr_b_r : unsigned (addr_width-1 downto 0); + +begin + + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/misc/dpram_1w1r_dist.vhd b/lib/misc/dpram_1w1r_dist.vhd index e07555c..4ce1232 100644 --- a/lib/misc/dpram_1w1r_dist.vhd +++ b/lib/misc/dpram_1w1r_dist.vhd @@ -1,84 +1,84 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w1r_dist.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r_dist is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clka : in STD_LOGIC; - clkb : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r_dist; - -architecture Behavioral of dpram_1w1r_dist is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - - attribute ram_style : string; - attribute ram_style of RAM: signal is "distributed"; - -begin - -process (clka) - begin - if clka'event and clka = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; - end if; -end process; - -process (clkb) - begin - if clkb'event and clkb = '1' then - if en_b = '1' then - dout_b <= RAM(to_integer(addr_b)); - end if; - end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w1r_dist.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r_dist is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clka : in STD_LOGIC; + clkb : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r_dist; + +architecture Behavioral of dpram_1w1r_dist is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + + attribute ram_style : string; + attribute ram_style of RAM: signal is "distributed"; + +begin + +process (clka) + begin + if clka'event and clka = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; + end if; +end process; + +process (clkb) + begin + if clkb'event and clkb = '1' then + if en_b = '1' then + dout_b <= RAM(to_integer(addr_b)); + end if; + end if; +end process; + + +end Behavioral; + diff --git a/lib/misc/dpram_1w2r1c_sim.vhd b/lib/misc/dpram_1w2r1c_sim.vhd index d9c9fb4..ef53770 100644 --- a/lib/misc/dpram_1w2r1c_sim.vhd +++ b/lib/misc/dpram_1w2r1c_sim.vhd @@ -1,86 +1,86 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w2r1c_sim.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_1w2r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w2r1c; - -architecture Behavioral of dpram_1w2r1c is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk) -begin -if clk'event and clk = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - addr_a_r <= addr_a; - end if; -end if; -end process; - -process (clk) -begin -if clk'event and clk = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w2r1c_sim.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_1w2r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w2r1c; + +architecture Behavioral of dpram_1w2r1c is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk) +begin +if clk'event and clk = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + addr_a_r <= addr_a; + end if; +end if; +end process; + +process (clk) +begin +if clk'event and clk = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + +end Behavioral; + diff --git a/lib/misc/dpram_1w2r1c_xil.vhd b/lib/misc/dpram_1w2r1c_xil.vhd index aa74983..e768dd4 100644 --- a/lib/misc/dpram_1w2r1c_xil.vhd +++ b/lib/misc/dpram_1w2r1c_xil.vhd @@ -1,80 +1,80 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_1w2r1c_xil.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_1w2r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w2r1c; - -architecture Behavioral of dpram_1w2r1c is - - -begin - -inst_dpram: entity work.dpram_2w2r2c - GENERIC MAP - ( - addr_width => addr_width, - data_width => data_width - ) - PORT MAP - ( - clk_a => clk, - clk_b => clk, - en_a => en_a, - en_b => en_b, - we_a => we_a, - we_b => '0', - addr_a => addr_a, - addr_b => addr_b, - din_a => din_a, - din_b => din_a, - dout_a => dout_a, - dout_b => dout_b - ); - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_1w2r1c_xil.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_1w2r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w2r1c; + +architecture Behavioral of dpram_1w2r1c is + + +begin + +inst_dpram: entity work.dpram_2w2r2c + GENERIC MAP + ( + addr_width => addr_width, + data_width => data_width + ) + PORT MAP + ( + clk_a => clk, + clk_b => clk, + en_a => en_a, + en_b => en_b, + we_a => we_a, + we_b => '0', + addr_a => addr_a, + addr_b => addr_b, + din_a => din_a, + din_b => din_a, + dout_a => dout_a, + dout_b => dout_b + ); + + +end Behavioral; + diff --git a/lib/misc/dpram_2w2r.vhd b/lib/misc/dpram_2w2r.vhd index e5a9e6a..eee8fdd 100644 --- a/lib/misc/dpram_2w2r.vhd +++ b/lib/misc/dpram_2w2r.vhd @@ -1,88 +1,88 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_2w2r.vhd,v 1.2 2009-01-14 20:26:29 Jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r; - -architecture Behavioral of dpram_2w2r is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - shared variable RAM : RAMtype; - -begin - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) := din_a; - end if; - dout_a <= RAM(to_integer(addr_a)); - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) := din_b; - end if; - dout_b <= RAM(to_integer(addr_b)); - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_2w2r.vhd,v 1.2 2009/01/14 20:26:29 Jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r; + +architecture Behavioral of dpram_2w2r is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + shared variable RAM : RAMtype; + +begin + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) := din_a; + end if; + dout_a <= RAM(to_integer(addr_a)); + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) := din_b; + end if; + dout_b <= RAM(to_integer(addr_b)); + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/misc/dpram_2w2r1c_sim.vhd b/lib/misc/dpram_2w2r1c_sim.vhd index 61f04e6..d6f97ec 100644 --- a/lib/misc/dpram_2w2r1c_sim.vhd +++ b/lib/misc/dpram_2w2r1c_sim.vhd @@ -1,88 +1,88 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_2w2r1c_sim.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r1c; - -architecture Behavioral of dpram_2w2r1c is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - signal contention : std_logic; -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - - contention <= en_a and we_a and en_b and we_b; - -process (clk) -begin -if clk'event and clk = '1' then - assert contention = '0' report "dpram_2w2r1c: Simultaneous write on Port A and Port B!" severity warning; - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - addr_a_r <= addr_a; - end if; - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) <= din_b; - end if; - addr_b_r <= addr_b; - end if; -end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_2w2r1c_sim.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r1c; + +architecture Behavioral of dpram_2w2r1c is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + signal contention : std_logic; +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + + contention <= en_a and we_a and en_b and we_b; + +process (clk) +begin +if clk'event and clk = '1' then + assert contention = '0' report "dpram_2w2r1c: Simultaneous write on Port A and Port B!" severity warning; + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + addr_a_r <= addr_a; + end if; + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) <= din_b; + end if; + addr_b_r <= addr_b; + end if; +end if; +end process; + +end Behavioral; + diff --git a/lib/misc/dpram_2w2r1c_xil.vhd b/lib/misc/dpram_2w2r1c_xil.vhd index 70c79d3..f1e7ee0 100644 --- a/lib/misc/dpram_2w2r1c_xil.vhd +++ b/lib/misc/dpram_2w2r1c_xil.vhd @@ -1,82 +1,82 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_2w2r1c_xil.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r1c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r1c; - -architecture Behavioral of dpram_2w2r1c is - - -begin - -inst_dpram: entity work.dpram_2w2r2c - GENERIC MAP - ( - addr_width => addr_width, - data_width => data_width - ) - PORT MAP - ( - clk_a => clk, - clk_b => clk, - en_a => en_a, - en_b => en_b, - we_a => we_a, - we_b => we_b, - addr_a => addr_a, - addr_b => addr_b, - din_a => din_a, - din_b => din_a, - dout_a => dout_a, - dout_b => dout_b - ); - - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_2w2r1c_xil.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r1c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r1c; + +architecture Behavioral of dpram_2w2r1c is + + +begin + +inst_dpram: entity work.dpram_2w2r2c + GENERIC MAP + ( + addr_width => addr_width, + data_width => data_width + ) + PORT MAP + ( + clk_a => clk, + clk_b => clk, + en_a => en_a, + en_b => en_b, + we_a => we_a, + we_b => we_b, + addr_a => addr_a, + addr_b => addr_b, + din_a => din_a, + din_b => din_a, + dout_a => dout_a, + dout_b => dout_b + ); + + +end Behavioral; + diff --git a/lib/misc/dpram_2w2r2c_sim.vhd b/lib/misc/dpram_2w2r2c_sim.vhd index aed56d3..5396ab4 100644 --- a/lib/misc/dpram_2w2r2c_sim.vhd +++ b/lib/misc/dpram_2w2r2c_sim.vhd @@ -1,95 +1,95 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_2w2r2c_sim.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c; - -architecture Behavioral of dpram_2w2r2c is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a, clk_b) -begin - if clk_a'event and clk_a = '1' and en_a = '1' and we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - elsif clk_b'event and clk_b = '1' and en_b = '1' and we_b = '1' then - RAM(to_integer(addr_b)) <= din_b; - end if; -end process; - -process (clk_a) -begin - if clk_a'event and clk_a = '1' then - if en_a = '1' then - addr_a_r <= addr_a; - end if; - end if; -end process; - -process (clk_b) -begin - if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; - end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_2w2r2c_sim.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c; + +architecture Behavioral of dpram_2w2r2c is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a, clk_b) +begin + if clk_a'event and clk_a = '1' and en_a = '1' and we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + elsif clk_b'event and clk_b = '1' and en_b = '1' and we_b = '1' then + RAM(to_integer(addr_b)) <= din_b; + end if; +end process; + +process (clk_a) +begin + if clk_a'event and clk_a = '1' then + if en_a = '1' then + addr_a_r <= addr_a; + end if; + end if; +end process; + +process (clk_b) +begin + if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; + end if; +end process; + +end Behavioral; + diff --git a/lib/misc/dpram_2w2r2c_xil.vhd b/lib/misc/dpram_2w2r2c_xil.vhd index 773e7cf..e86daf7 100644 --- a/lib/misc/dpram_2w2r2c_xil.vhd +++ b/lib/misc/dpram_2w2r2c_xil.vhd @@ -1,93 +1,93 @@ -------------------------------------------------------------------------- --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/dpram_2w2r2c_xil.vhd,v 1.1 2013-02-07 14:15:38 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c; - -architecture Behavioral of dpram_2w2r2c is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - shared variable RAM : RAMtype; - -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) := din_a; - end if; - addr_a_r <= addr_a; - end if; -end if; -end process; - - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) := din_b; - end if; - addr_b_r <= addr_b; - end if; -end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/dpram_2w2r2c_xil.vhd,v 1.1 2013/02/07 14:15:38 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c; + +architecture Behavioral of dpram_2w2r2c is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + shared variable RAM : RAMtype; + +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) := din_a; + end if; + addr_a_r <= addr_a; + end if; +end if; +end process; + + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) := din_b; + end if; + addr_b_r <= addr_b; + end if; +end if; +end process; + +end Behavioral; + diff --git a/lib/misc/flash_port_wb.vhd b/lib/misc/flash_port_wb.vhd index 9dcc7fe..296536f 100644 --- a/lib/misc/flash_port_wb.vhd +++ b/lib/misc/flash_port_wb.vhd @@ -1,293 +1,293 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/flash_port_wb.vhd,v 1.2 2010-03-13 11:06:43 Jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use work.async_types.all; - - ------------------------------------------------------------------ -entity flash_port_wb is - Generic - ( - f_sysclk : real := 100.0; - addr_width : natural := 32; - data_width : natural := 32; - async_timespec : async_timespec_t - ); - Port - ( - CLK_I : in STD_LOGIC; - RST_I : in STD_LOGIC; - CYC_I : in STD_LOGIC; - STB_I : in STD_LOGIC; - WE_I : in STD_LOGIC; - ACK_O : out STD_LOGIC; - SRDY_O : out STD_LOGIC; - MRDY_I : in STD_LOGIC; - ADDR_I : in unsigned(31 downto 0); - DAT_I : in unsigned(31 downto 0); - DAT_O : out unsigned(31 downto 0); - port_bsyi : in std_logic; - port_bsyo : out std_logic; - port_a : out unsigned(addr_width-1 downto 0); - port_di : in unsigned(data_width-1 downto 0); - port_do : out unsigned(data_width-1 downto 0); - port_d_drv : out STD_LOGIC; - port_wr : out STD_LOGIC; - port_rd : out STD_LOGIC; - flash_cs : out std_logic; - flash_rst : out std_logic - ); -end flash_port_wb; - -architecture Behavioral of flash_port_wb is - - type async_t is record - cs : std_logic; - wr : std_logic; - rd : std_logic; - rst : std_logic; - drive_d : std_logic; - end record; - - type async_state_t is (start, reset, idle, go, leadin_rd, read, leadin_wr, write, leadout_rd, leadout_wr, release); - - signal s, sn : async_state_t; - signal as : async_t; - signal ack : std_logic; - signal cc_rst : std_logic; - signal cycle_cnt : natural range 0 to 31; - signal cycle_reload : natural range 0 to 31; - signal rdy : std_logic; - signal rdyo : std_logic; - signal en : std_logic; - signal we_reg : std_logic; - signal data_reg : unsigned(data_width-1 downto 0); - signal addr_reg : unsigned(addr_width-1 downto 0); - - ------------------------------------------------------------------ - begin - - SRDY_O <= CYC_I and rdyo; - en <= CYC_I and STB_I; - port_a <= addr_reg; - port_do <= data_reg; - port_d_drv <= as.drive_d; - port_wr <= (not async_timespec.pol_we) xor as.wr; - port_rd <= (not async_timespec.pol_oe) xor as.rd; - - proc_cycle_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if cc_rst = '1' then - cycle_cnt <= cycle_reload; - elsif cycle_cnt /= 0 then - cycle_cnt <= cycle_cnt - 1; - end if; - end if; - end process; - - ------------------------------------------------------------------ - proc_state_next: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - s <= start; - else - s <= sn; - end if; - end if; - end process; - - proc_state: - process(s, cycle_cnt, en, we_reg, port_bsyi) - begin - - cycle_reload <= to_cycles(async_timespec.T_pulse_rst, f_sysclk); - cc_rst <= '0'; - as.rst <= '0'; - as.cs <= '0'; - as.wr <= '0'; - as.rd <= '0'; - as.drive_d <= '0'; - ack <= '0'; - rdy <= '0'; - port_bsyo <= '1'; - - sn <= s; - case s is - - when start => - cc_rst <= '1'; - sn <= reset; - when reset => - as.rst <= '1'; - if cycle_cnt = 0 then - sn <= idle; - end if; - when idle => - port_bsyo <= '0'; - rdy <= '1'; - if en = '1' then - sn <= go; - end if; - when go => - port_bsyo <= '0'; - if port_bsyi = '0' then - as.cs <= '1'; - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_leadin, f_sysclk)-1; - if we_reg = '0' then - sn <= leadin_rd; - else - sn <= leadin_wr; - end if; - end if; - when leadin_rd => - as.cs <= '1'; - if cycle_cnt = 0 then - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk)-1; - as.rd <= '1'; - sn <= read; - end if; - - when leadin_wr => - as.cs <= '1'; - if cycle_cnt = 0 then - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_pulse_wr, f_sysclk)-1; - as.wr <= '1'; - as.drive_d <= '1'; - sn <= write; - end if; - - when read => - as.cs <= '1'; - as.rd <= '1'; - if cycle_cnt = 0 then - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk)-1; --- as.rd <= '0'; - sn <= leadout_rd; - ack <= '1'; - end if; - - when write => - as.drive_d <= '1'; - as.cs <= '1'; - as.wr <= '1'; - if cycle_cnt = 0 then - as.wr <= '0'; - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk)-1; - sn <= leadout_wr; --- ack <= '1'; - end if; - - when leadout_rd => - as.cs <= '1'; - if cycle_cnt = 0 then - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk)-1; - sn <= release; - as.cs <= '0'; - end if; - - when leadout_wr => - as.cs <= '1'; - as.drive_d <= '1'; - if cycle_cnt = 0 then - cc_rst <= '1'; - cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk)-1; - sn <= release; - as.cs <= '0'; - end if; - - when release => - if cycle_cnt = 0 then - sn <= idle; - end if; - - when others => - sn <= idle; - - end case; - end process; - - ------------------------------------------------------------------ - output_ctrl: - process(CLK_I) - begin - if rising_edge(CLK_I) then - flash_cs <= (not async_timespec.pol_cs) xor as.cs; - flash_rst <= (not async_timespec.pol_rst) xor as.rst; - end if; - end process; - - ------------------------------------------------------------------ - din_register: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if as.rd = '1' then - DAT_O(data_width-1 downto 0) <= port_di; - end if; - end if; - end process; - - ------------------------------------------------------------------ - data_register: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if en = '1' and rdy = '1' then - we_reg <= WE_I; - data_reg <= DAT_I(data_width-1 downto 0); - end if; - end if; - end process; - - ------------------------------------------------------------------ - addr_register: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if en = '1' and rdy = '1' then - addr_reg <= ADDR_I(addr_width-1 downto 0); - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_SRDY: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - rdyo <= '1'; - elsif en = '1' then - rdyo <= rdy and not rdyo; - end if; - end if; - end process; - - ------------------------------------------------------------------ - output_ACK: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - ACK_O <= '0'; - else - ACK_O <= ack; - end if; - end if; - end process; - - ------------------------------------------------------------------ - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/flash_port_wb.vhd,v 1.2 2010/03/13 11:06:43 Jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.async_types.all; + + ------------------------------------------------------------------ +entity flash_port_wb is + Generic + ( + f_sysclk : real := 100.0; + addr_width : natural := 32; + data_width : natural := 32; + async_timespec : async_timespec_t + ); + Port + ( + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + port_bsyi : in std_logic; + port_bsyo : out std_logic; + port_a : out unsigned(addr_width-1 downto 0); + port_di : in unsigned(data_width-1 downto 0); + port_do : out unsigned(data_width-1 downto 0); + port_d_drv : out STD_LOGIC; + port_wr : out STD_LOGIC; + port_rd : out STD_LOGIC; + flash_cs : out std_logic; + flash_rst : out std_logic + ); +end flash_port_wb; + +architecture Behavioral of flash_port_wb is + + type async_t is record + cs : std_logic; + wr : std_logic; + rd : std_logic; + rst : std_logic; + drive_d : std_logic; + end record; + + type async_state_t is (start, reset, idle, go, leadin_rd, read, leadin_wr, write, leadout_rd, leadout_wr, release); + + signal s, sn : async_state_t; + signal as : async_t; + signal ack : std_logic; + signal cc_rst : std_logic; + signal cycle_cnt : natural range 0 to 31; + signal cycle_reload : natural range 0 to 31; + signal rdy : std_logic; + signal rdyo : std_logic; + signal en : std_logic; + signal we_reg : std_logic; + signal data_reg : unsigned(data_width-1 downto 0); + signal addr_reg : unsigned(addr_width-1 downto 0); + + ------------------------------------------------------------------ + begin + + SRDY_O <= CYC_I and rdyo; + en <= CYC_I and STB_I; + port_a <= addr_reg; + port_do <= data_reg; + port_d_drv <= as.drive_d; + port_wr <= (not async_timespec.pol_we) xor as.wr; + port_rd <= (not async_timespec.pol_oe) xor as.rd; + + proc_cycle_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if cc_rst = '1' then + cycle_cnt <= cycle_reload; + elsif cycle_cnt /= 0 then + cycle_cnt <= cycle_cnt - 1; + end if; + end if; + end process; + + ------------------------------------------------------------------ + proc_state_next: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + s <= start; + else + s <= sn; + end if; + end if; + end process; + + proc_state: + process(s, cycle_cnt, en, we_reg, port_bsyi) + begin + + cycle_reload <= to_cycles(async_timespec.T_pulse_rst, f_sysclk); + cc_rst <= '0'; + as.rst <= '0'; + as.cs <= '0'; + as.wr <= '0'; + as.rd <= '0'; + as.drive_d <= '0'; + ack <= '0'; + rdy <= '0'; + port_bsyo <= '1'; + + sn <= s; + case s is + + when start => + cc_rst <= '1'; + sn <= reset; + when reset => + as.rst <= '1'; + if cycle_cnt = 0 then + sn <= idle; + end if; + when idle => + port_bsyo <= '0'; + rdy <= '1'; + if en = '1' then + sn <= go; + end if; + when go => + port_bsyo <= '0'; + if port_bsyi = '0' then + as.cs <= '1'; + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_leadin, f_sysclk)-1; + if we_reg = '0' then + sn <= leadin_rd; + else + sn <= leadin_wr; + end if; + end if; + when leadin_rd => + as.cs <= '1'; + if cycle_cnt = 0 then + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_pulse_rd, f_sysclk)-1; + as.rd <= '1'; + sn <= read; + end if; + + when leadin_wr => + as.cs <= '1'; + if cycle_cnt = 0 then + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_pulse_wr, f_sysclk)-1; + as.wr <= '1'; + as.drive_d <= '1'; + sn <= write; + end if; + + when read => + as.cs <= '1'; + as.rd <= '1'; + if cycle_cnt = 0 then + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk)-1; +-- as.rd <= '0'; + sn <= leadout_rd; + ack <= '1'; + end if; + + when write => + as.drive_d <= '1'; + as.cs <= '1'; + as.wr <= '1'; + if cycle_cnt = 0 then + as.wr <= '0'; + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_leadout, f_sysclk)-1; + sn <= leadout_wr; +-- ack <= '1'; + end if; + + when leadout_rd => + as.cs <= '1'; + if cycle_cnt = 0 then + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk)-1; + sn <= release; + as.cs <= '0'; + end if; + + when leadout_wr => + as.cs <= '1'; + as.drive_d <= '1'; + if cycle_cnt = 0 then + cc_rst <= '1'; + cycle_reload <= to_cycles(async_timespec.T_release, f_sysclk)-1; + sn <= release; + as.cs <= '0'; + end if; + + when release => + if cycle_cnt = 0 then + sn <= idle; + end if; + + when others => + sn <= idle; + + end case; + end process; + + ------------------------------------------------------------------ + output_ctrl: + process(CLK_I) + begin + if rising_edge(CLK_I) then + flash_cs <= (not async_timespec.pol_cs) xor as.cs; + flash_rst <= (not async_timespec.pol_rst) xor as.rst; + end if; + end process; + + ------------------------------------------------------------------ + din_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if as.rd = '1' then + DAT_O(data_width-1 downto 0) <= port_di; + end if; + end if; + end process; + + ------------------------------------------------------------------ + data_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if en = '1' and rdy = '1' then + we_reg <= WE_I; + data_reg <= DAT_I(data_width-1 downto 0); + end if; + end if; + end process; + + ------------------------------------------------------------------ + addr_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if en = '1' and rdy = '1' then + addr_reg <= ADDR_I(addr_width-1 downto 0); + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_SRDY: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + rdyo <= '1'; + elsif en = '1' then + rdyo <= rdy and not rdyo; + end if; + end if; + end process; + + ------------------------------------------------------------------ + output_ACK: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + ACK_O <= '0'; + else + ACK_O <= ack; + end if; + end if; + end process; + + ------------------------------------------------------------------ + +end Behavioral; diff --git a/lib/misc/lcd_port.vhd b/lib/misc/lcd_port.vhd index 11f97eb..f21cd82 100644 --- a/lib/misc/lcd_port.vhd +++ b/lib/misc/lcd_port.vhd @@ -1,69 +1,69 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/lcd_port.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - - ------------------------------------------------------------------ -entity lcd_port is - Port ( - rst : in std_logic; - clk : in std_logic; - we : in std_logic; - din : in unsigned(7 downto 0); - dout : out unsigned(7 downto 0); - lcd_d : inout unsigned(3 downto 0); - lcd_e : out std_logic; - lcd_rs : out std_logic; - lcd_rw : out std_logic - ); - end lcd_port; - -architecture Behavioral of lcd_port is - - constant clcd_e : integer := 7; - constant clcd_rs : integer := 6; - constant clcd_rw : integer := 5; - - type lcd_t is record - d : unsigned(3 downto 0); - e : std_logic; - rs : std_logic; - rw : std_logic; - end record; - - ------------------------------------------------------------------ - begin - - proc_lcd_port: - process(rst, clk) - variable vlcd : lcd_t; - begin - if (rst = '1') then - dout <= (others => '0'); - vlcd.d := (others => '0'); - vlcd.e := '0'; - vlcd.rw := '1'; - vlcd.rs := '0'; - elsif rising_edge(clk) then - dout <= unsigned("0000" & lcd_d); - if we = '1' then - vlcd.d := din(3 downto 0); - vlcd.e := din(clcd_e); - vlcd.rs := din(clcd_rs); - vlcd.rw := din(clcd_rw); - end if; - end if; - if vlcd.rw = '0' then - lcd_d <= unsigned(vlcd.d); - else - lcd_d <= (others => 'Z'); - end if; - lcd_e <= vlcd.e; - lcd_rs <= vlcd.rs; - lcd_rw <= vlcd.rw; - end process; - ------------------------------------------------------------------ - -end Behavioral; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/lcd_port.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + + ------------------------------------------------------------------ +entity lcd_port is + Port ( + rst : in std_logic; + clk : in std_logic; + we : in std_logic; + din : in unsigned(7 downto 0); + dout : out unsigned(7 downto 0); + lcd_d : inout unsigned(3 downto 0); + lcd_e : out std_logic; + lcd_rs : out std_logic; + lcd_rw : out std_logic + ); + end lcd_port; + +architecture Behavioral of lcd_port is + + constant clcd_e : integer := 7; + constant clcd_rs : integer := 6; + constant clcd_rw : integer := 5; + + type lcd_t is record + d : unsigned(3 downto 0); + e : std_logic; + rs : std_logic; + rw : std_logic; + end record; + + ------------------------------------------------------------------ + begin + + proc_lcd_port: + process(rst, clk) + variable vlcd : lcd_t; + begin + if (rst = '1') then + dout <= (others => '0'); + vlcd.d := (others => '0'); + vlcd.e := '0'; + vlcd.rw := '1'; + vlcd.rs := '0'; + elsif rising_edge(clk) then + dout <= unsigned("0000" & lcd_d); + if we = '1' then + vlcd.d := din(3 downto 0); + vlcd.e := din(clcd_e); + vlcd.rs := din(clcd_rs); + vlcd.rw := din(clcd_rw); + end if; + end if; + if vlcd.rw = '0' then + lcd_d <= unsigned(vlcd.d); + else + lcd_d <= (others => 'Z'); + end if; + lcd_e <= vlcd.e; + lcd_rs <= vlcd.rs; + lcd_rw <= vlcd.rw; + end process; + ------------------------------------------------------------------ + +end Behavioral; diff --git a/lib/misc/oneshot.vhd b/lib/misc/oneshot.vhd index 2f5d8bd..0e7aa83 100644 --- a/lib/misc/oneshot.vhd +++ b/lib/misc/oneshot.vhd @@ -1,223 +1,223 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 21:52:19 10/22/05 --- Design Name: --- Module Name: oneshot - Behavioral --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/oneshot.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ --- Component Template --- --- COMPONENT oneshot --- GENERIC (mode : integer); --- PORT( --- rst : IN std_logic; --- clk : IN std_logic; --- input : IN std_logic; --- output : OUT std_logic --- ); --- END COMPONENT; --- --- Instantation Template --- --- oneshot_int: oneshot --- GENERIC MAP ( --- mode => 1) --- PORT MAP( --- rst => , --- clk => , --- input => , --- output => --- ); --- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - -entity oneshot is - Generic ( mode : integer range 0 to 2 := 1); - Port ( rst : in std_logic; - clk : in std_logic; - input : in std_logic; - output : out std_logic); -end oneshot; - -architecture Behavioral of oneshot is - -type shot_state_t is (shot_pos_st, shot_neg_st, release_pos_st, release_neg_st); - -signal shot_cs : shot_state_t; -signal shot_ns : shot_state_t; - -begin - -mode_0: -if mode = 0 generate -begin - shot_clk: process(rst, clk, shot_ns, input) - begin - if (rst = '1') then - if (input = '1') then - shot_cs <= release_pos_st; - else - shot_cs <= release_neg_st; - end if; - else - if rising_edge(clk) then - shot_cs <= shot_ns; - end if; - end if; - end process; - - shot_in: process(rst, clk, input, shot_cs) - begin - shot_ns <= shot_cs; - case shot_cs is - when release_pos_st => - if (input = '0') then - shot_ns <= shot_neg_st; - end if; - when shot_neg_st => - shot_ns <= release_neg_st; - when release_neg_st => - if (input = '1') then - shot_ns <= release_pos_st; - end if; - when others => null; - end case; - end process; - - shot_out: process(shot_cs) - begin - output <= '0'; - case shot_cs is - when shot_pos_st => - output <= '1'; - when shot_neg_st => - output <= '1'; - when others => null; - end case; - end process; -end generate; - -mode_1: -if mode = 1 generate -begin - shot_clk: process(rst, clk, shot_ns, input) - begin - if (rst = '1') then - if (input = '1') then - shot_cs <= release_pos_st; - else - shot_cs <= release_neg_st; - end if; - else - if rising_edge(clk) then - shot_cs <= shot_ns; - end if; - end if; - end process; - - shot_in: process(rst, clk, input, shot_cs) - begin - shot_ns <= shot_cs; - case shot_cs is - when shot_pos_st => - shot_ns <= release_pos_st; - when release_pos_st => - if (input = '0') then - shot_ns <= release_neg_st; - end if; - when release_neg_st => - if (input = '1') then - shot_ns <= shot_pos_st; - end if; - when others => null; - end case; - end process; - - shot_out: process(shot_cs) - begin - output <= '0'; - case shot_cs is - when shot_pos_st => - output <= '1'; - when shot_neg_st => - output <= '1'; - when others => null; - end case; - end process; -end generate; - -mode_2: -if mode = 2 generate -begin - shot_clk: process(rst, clk, shot_ns, input) - begin - if (rst = '1') then - if (input = '1') then - shot_cs <= release_pos_st; - else - shot_cs <= release_neg_st; - end if; - else - if rising_edge(clk) then - shot_cs <= shot_ns; - end if; - end if; - end process; - - shot_in: process(rst, clk, input, shot_cs) - begin - shot_ns <= shot_cs; - case shot_cs is - when shot_pos_st => - shot_ns <= release_pos_st; - when release_pos_st => - if (input = '0') then - shot_ns <= shot_neg_st; - end if; - when shot_neg_st => - shot_ns <= release_neg_st; - when release_neg_st => - if (input = '1') then - shot_ns <= shot_pos_st; - end if; - end case; - end process; - - shot_out: process(shot_cs) - begin - output <= '0'; - case shot_cs is - when shot_pos_st => - output <= '1'; - when shot_neg_st => - output <= '1'; - when others => null; - end case; - end process; -end generate; - - - -end Behavioral; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 21:52:19 10/22/05 +-- Design Name: +-- Module Name: oneshot - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/oneshot.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +-- Component Template +-- +-- COMPONENT oneshot +-- GENERIC (mode : integer); +-- PORT( +-- rst : IN std_logic; +-- clk : IN std_logic; +-- input : IN std_logic; +-- output : OUT std_logic +-- ); +-- END COMPONENT; +-- +-- Instantation Template +-- +-- oneshot_int: oneshot +-- GENERIC MAP ( +-- mode => 1) +-- PORT MAP( +-- rst => , +-- clk => , +-- input => , +-- output => +-- ); +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity oneshot is + Generic ( mode : integer range 0 to 2 := 1); + Port ( rst : in std_logic; + clk : in std_logic; + input : in std_logic; + output : out std_logic); +end oneshot; + +architecture Behavioral of oneshot is + +type shot_state_t is (shot_pos_st, shot_neg_st, release_pos_st, release_neg_st); + +signal shot_cs : shot_state_t; +signal shot_ns : shot_state_t; + +begin + +mode_0: +if mode = 0 generate +begin + shot_clk: process(rst, clk, shot_ns, input) + begin + if (rst = '1') then + if (input = '1') then + shot_cs <= release_pos_st; + else + shot_cs <= release_neg_st; + end if; + else + if rising_edge(clk) then + shot_cs <= shot_ns; + end if; + end if; + end process; + + shot_in: process(rst, clk, input, shot_cs) + begin + shot_ns <= shot_cs; + case shot_cs is + when release_pos_st => + if (input = '0') then + shot_ns <= shot_neg_st; + end if; + when shot_neg_st => + shot_ns <= release_neg_st; + when release_neg_st => + if (input = '1') then + shot_ns <= release_pos_st; + end if; + when others => null; + end case; + end process; + + shot_out: process(shot_cs) + begin + output <= '0'; + case shot_cs is + when shot_pos_st => + output <= '1'; + when shot_neg_st => + output <= '1'; + when others => null; + end case; + end process; +end generate; + +mode_1: +if mode = 1 generate +begin + shot_clk: process(rst, clk, shot_ns, input) + begin + if (rst = '1') then + if (input = '1') then + shot_cs <= release_pos_st; + else + shot_cs <= release_neg_st; + end if; + else + if rising_edge(clk) then + shot_cs <= shot_ns; + end if; + end if; + end process; + + shot_in: process(rst, clk, input, shot_cs) + begin + shot_ns <= shot_cs; + case shot_cs is + when shot_pos_st => + shot_ns <= release_pos_st; + when release_pos_st => + if (input = '0') then + shot_ns <= release_neg_st; + end if; + when release_neg_st => + if (input = '1') then + shot_ns <= shot_pos_st; + end if; + when others => null; + end case; + end process; + + shot_out: process(shot_cs) + begin + output <= '0'; + case shot_cs is + when shot_pos_st => + output <= '1'; + when shot_neg_st => + output <= '1'; + when others => null; + end case; + end process; +end generate; + +mode_2: +if mode = 2 generate +begin + shot_clk: process(rst, clk, shot_ns, input) + begin + if (rst = '1') then + if (input = '1') then + shot_cs <= release_pos_st; + else + shot_cs <= release_neg_st; + end if; + else + if rising_edge(clk) then + shot_cs <= shot_ns; + end if; + end if; + end process; + + shot_in: process(rst, clk, input, shot_cs) + begin + shot_ns <= shot_cs; + case shot_cs is + when shot_pos_st => + shot_ns <= release_pos_st; + when release_pos_st => + if (input = '0') then + shot_ns <= shot_neg_st; + end if; + when shot_neg_st => + shot_ns <= release_neg_st; + when release_neg_st => + if (input = '1') then + shot_ns <= shot_pos_st; + end if; + end case; + end process; + + shot_out: process(shot_cs) + begin + output <= '0'; + case shot_cs is + when shot_pos_st => + output <= '1'; + when shot_neg_st => + output <= '1'; + when others => null; + end case; + end process; +end generate; + + + +end Behavioral; diff --git a/lib/misc/pkg_template.vhd b/lib/misc/pkg_template.vhd index fe866e8..29a9f31 100644 --- a/lib/misc/pkg_template.vhd +++ b/lib/misc/pkg_template.vhd @@ -1,18 +1,18 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/pkg_template.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -package template_pkg is - -- Constants - -- Types - -- Functions - -end template_pkg; - -package body template_pkg is - -end template_pkg; - +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/pkg_template.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +package template_pkg is + -- Constants + -- Types + -- Functions + +end template_pkg; + +package body template_pkg is + +end template_pkg; + diff --git a/lib/misc/singleshot.vhd b/lib/misc/singleshot.vhd index 25f7013..663c8c6 100644 --- a/lib/misc/singleshot.vhd +++ b/lib/misc/singleshot.vhd @@ -1,155 +1,155 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 21:52:19 10/22/05 --- Design Name: --- Module Name: singleshot - Behavioral --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/singleshot.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ --- Component Template --- --- COMPONENT singleshot --- GENERIC (mode : integer); --- PORT( --- rst : IN std_logic; --- clk : IN std_logic; --- input : IN std_logic; --- output : OUT std_logic --- ); --- END COMPONENT; --- --- Instantation Template --- --- singleshot_int: oneshot --- GENERIC MAP ( --- mode => 1) --- PORT MAP( --- rst => , --- clk => , --- input => , --- output => --- ); --- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -entity singleshot is - Generic ( mode : integer range 0 to 2 := 1); - Port ( rst : in std_logic; - clk : in std_logic; - input : in std_logic; - output : out std_logic); -end singleshot; - -architecture Behavioral of singleshot is - -type s_t is (idle, shot_in, active, shot_out); -signal s, sn : s_t; - -begin - -process (rst, clk, sn) -begin - if rising_edge(clk) then - if rst = '1' then - s <= idle; - else - s <= sn; - end if; - end if; -end process; - -mode_1: -if mode = 1 generate -begin - process (input, s) - begin - output <= '0'; - sn <= s; - case s is - when idle => - if input = '1' then - sn <= shot_in; - end if; - when shot_in => - output <= '1'; - sn <= active; - when active => - if input = '0' then - sn <= shot_out; - end if; - when shot_out => - sn <= idle; - when others => null; - end case; - end process; -end generate; - -mode_0: -if mode = 0 generate -begin - process (input, s) - begin - output <= '0'; - sn <= s; - case s is - when idle => - if input = '1' then - sn <= shot_in; - end if; - when shot_in => - sn <= active; - when active => - if input = '0' then - sn <= shot_out; - end if; - when shot_out => - output <= '1'; - sn <= idle; - when others => null; - end case; - end process; -end generate; - -mode_2: -if mode = 2 generate -begin - process (input, s) - begin - output <= '0'; - sn <= s; - case s is - when idle => - if input = '1' then - sn <= shot_in; - end if; - when shot_in => - output <= '1'; - sn <= active; - when active => - if input = '0' then - sn <= shot_out; - end if; - when shot_out => - output <= '1'; - sn <= idle; - when others => null; - end case; - end process; -end generate; - -end Behavioral; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 21:52:19 10/22/05 +-- Design Name: +-- Module Name: singleshot - Behavioral +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/singleshot.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +-- Component Template +-- +-- COMPONENT singleshot +-- GENERIC (mode : integer); +-- PORT( +-- rst : IN std_logic; +-- clk : IN std_logic; +-- input : IN std_logic; +-- output : OUT std_logic +-- ); +-- END COMPONENT; +-- +-- Instantation Template +-- +-- singleshot_int: oneshot +-- GENERIC MAP ( +-- mode => 1) +-- PORT MAP( +-- rst => , +-- clk => , +-- input => , +-- output => +-- ); +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity singleshot is + Generic ( mode : integer range 0 to 2 := 1); + Port ( rst : in std_logic; + clk : in std_logic; + input : in std_logic; + output : out std_logic); +end singleshot; + +architecture Behavioral of singleshot is + +type s_t is (idle, shot_in, active, shot_out); +signal s, sn : s_t; + +begin + +process (rst, clk, sn) +begin + if rising_edge(clk) then + if rst = '1' then + s <= idle; + else + s <= sn; + end if; + end if; +end process; + +mode_1: +if mode = 1 generate +begin + process (input, s) + begin + output <= '0'; + sn <= s; + case s is + when idle => + if input = '1' then + sn <= shot_in; + end if; + when shot_in => + output <= '1'; + sn <= active; + when active => + if input = '0' then + sn <= shot_out; + end if; + when shot_out => + sn <= idle; + when others => null; + end case; + end process; +end generate; + +mode_0: +if mode = 0 generate +begin + process (input, s) + begin + output <= '0'; + sn <= s; + case s is + when idle => + if input = '1' then + sn <= shot_in; + end if; + when shot_in => + sn <= active; + when active => + if input = '0' then + sn <= shot_out; + end if; + when shot_out => + output <= '1'; + sn <= idle; + when others => null; + end case; + end process; +end generate; + +mode_2: +if mode = 2 generate +begin + process (input, s) + begin + output <= '0'; + sn <= s; + case s is + when idle => + if input = '1' then + sn <= shot_in; + end if; + when shot_in => + output <= '1'; + sn <= active; + when active => + if input = '0' then + sn <= shot_out; + end if; + when shot_out => + output <= '1'; + sn <= idle; + when others => null; + end case; + end process; +end generate; + +end Behavioral; diff --git a/lib/misc/tb_template.vhd b/lib/misc/tb_template.vhd index f96f294..d17b82f 100644 --- a/lib/misc/tb_template.vhd +++ b/lib/misc/tb_template.vhd @@ -1,63 +1,63 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/tb_template.vhd,v 1.1 2008-08-23 08:20:29 Jens Exp $ ------------------------------------------------------------------------ -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.MATH_REAL.ALL; -USE IEEE.NUMERIC_STD.ALL; -USE STD.TEXTIO.ALL; - --- LIBRARY WORK; --- USE.YOURLIB.WHATELSE - -ENTITY tb_template IS -END tb_template; - -ARCHITECTURE behavior OF tb_template IS - - -- Component Declaration for the Unit Under Test (UUT) - COMPONENT your_comp - GENERIC - ( - ); - PORT - ( - ); - END COMPONENT; - - --Constants - constant PERIOD : time := 10 ns; - - --Inputs - signal clk : STD_LOGIC := '0'; - - --Outputs - -BEGIN - - -- Instantiate the Unit Under Test (UUT) - uut: your_comp - GENERIC MAP - ( - ) - PORT MAP - ( - ); - - tb_clk : PROCESS - BEGIN - clk <= not clk; - wait for PERIOD/2; - END PROCESS; - - BEGIN - - -- Wait 100 ns for global reset to finish - wait for 4*PERIOD; - - assert false report "Test finished" severity error; - wait; - - END PROCESS; - -END tb_template; +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/tb_template.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ +----------------------------------------------------------------------- +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.MATH_REAL.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE STD.TEXTIO.ALL; + +-- LIBRARY WORK; +-- USE.YOURLIB.WHATELSE + +ENTITY tb_template IS +END tb_template; + +ARCHITECTURE behavior OF tb_template IS + + -- Component Declaration for the Unit Under Test (UUT) + COMPONENT your_comp + GENERIC + ( + ); + PORT + ( + ); + END COMPONENT; + + --Constants + constant PERIOD : time := 10 ns; + + --Inputs + signal clk : STD_LOGIC := '0'; + + --Outputs + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: your_comp + GENERIC MAP + ( + ) + PORT MAP + ( + ); + + tb_clk : PROCESS + BEGIN + clk <= not clk; + wait for PERIOD/2; + END PROCESS; + + BEGIN + + -- Wait 100 ns for global reset to finish + wait for 4*PERIOD; + + assert false report "Test finished" severity error; + wait; + + END PROCESS; + +END tb_template; diff --git a/lib/misc/utils_pkg.vhd b/lib/misc/utils_pkg.vhd index 7212852..916818c 100644 --- a/lib/misc/utils_pkg.vhd +++ b/lib/misc/utils_pkg.vhd @@ -1,196 +1,196 @@ ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/misc/utils_pkg.vhd,v 1.6 2010-03-22 07:25:40 Jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; -use IEEE.MATH_REAL.ALL; - -package utils_pkg is - - -- Constants - - -- Functions - function MIN (X, Y: INTEGER) return INTEGER; - function MAX (X, Y: INTEGER) return INTEGER; - - function NextPowerOfTwo(x : real) return real; - function NextExpBaseTwo(x : real) return real; - function NextPowerOfTwo(x : natural) return natural; - function NextExpBaseTwo(x : natural) return natural; - function GCD(a, b : natural) return natural; - function LCM(a, b : natural) return natural; - function UTILS_PERIOD_NS(f_in_MHz : real) return real; - function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural; - function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural; - function f_correct(f : real) return natural; - -end utils_pkg; - - -package body utils_pkg is - - ------------------------------------------------------------- - function MIN (X, Y: INTEGER) return INTEGER is - variable res : integer := X; - begin - if Y < X then - res := Y; - end if; - - return res; - - end MIN; - - ------------------------------------------------------------- - function MAX (X, Y: INTEGER) return INTEGER is - variable res : integer := X; - begin - if Y > X then - res := Y; - end if; - - return res; - - end MAX; - - ------------------------------------------------------------- - function NextExpBaseTwo(x : real) return real is - begin - return ceil(log2(x)); - end NextExpBaseTwo; - - ------------------------------------------------------------- - function NextPowerOfTwo(x : real) return real is - begin - - return 2.0**NextExpBaseTwo(x); - end NextPowerOfTwo; - - ------------------------------------------------------------- - function NextExpBaseTwo(x : natural) return natural is - begin - return natural(NextExpBaseTwo(real(x))); - end NextExpBaseTwo; - - ------------------------------------------------------------- - function NextPowerOfTwo(x : natural) return natural is - begin - - return 2**NextExpBaseTwo(x); - end NextPowerOfTwo; - - ------------------------------------------------------------- - function GCD(a, b : natural) return natural is - variable aa : natural; - variable bb : natural; - begin - aa := a; - bb := b; - while bb /= 0 loop - if aa > bb then - aa := aa - bb; - else - bb := bb - aa; - end if; - end loop; - - return aa; - - end GCD; - - ------------------------------------------------------------- - function LCM(a, b : natural) return natural is - begin - - return (a * b)/GCD(a, b); - - end LCM; - - ------------------------------------------------------------- - function UTILS_PERIOD_NS(f_in_MHz : real) return real is - begin - - return 1.0E3/f_in_MHz; - - end UTILS_PERIOD_NS; - - ------------------------------------------------------------- - function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural is - variable f_in : natural; - variable f_out : natural; - variable C : natural; - variable M : natural; - variable D : natural; - begin - C := f_correct(f_out_MHz); - if C < 2 then - C := f_correct(f_in_MHz); - end if; - - f_out := natural(ceil(real(C)*f_out_MHz)); - f_in := natural(ceil(real(C)*f_in_MHz)); - - M := LCM(f_in, f_out)/f_in; - D := f_in/GCD(f_in, f_out); - - assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure; - - if M = 1 then - M := 2; - end if; - - return M; - - end UTILS_FREQ_M; - - ------------------------------------------------------------- - function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural is - variable f_in : natural; - variable f_out : natural; - variable C : natural; - variable M : natural; - variable D : natural; - begin - C := f_correct(f_out_MHz); - if C < 2 then - C := f_correct(f_in_MHz); - end if; - - f_out := natural(ceil(real(C)*f_out_MHz)); - f_in := natural(ceil(real(C)*f_in_MHz)); - - M := LCM(f_in, f_out)/f_in; - D := f_in/GCD(f_in, f_out); - - assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure; - - if M = 1 then - D := 2*D; - end if; - - return D; - - end UTILS_FREQ_D; - - ------------------------------------------------------------- - function f_correct(f : real) return natural is - constant MAX_ITER : positive := 100; - constant MAX_ERR : real := 0.01; - variable fpart : real; - variable err : real; - begin - for i in 1 to MAX_ITER loop - fpart := real(i)*f - ceil(real(i)*f); - err := abs(fpart); - if err < max_err then - return i; - end if; - end loop; - end f_correct; - - ------------------------------------------------------------- -end utils_pkg; - - +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/misc/utils_pkg.vhd,v 1.6 2010/03/22 07:25:40 Jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use IEEE.MATH_REAL.ALL; + +package utils_pkg is + + -- Constants + + -- Functions + function MIN (X, Y: INTEGER) return INTEGER; + function MAX (X, Y: INTEGER) return INTEGER; + + function NextPowerOfTwo(x : real) return real; + function NextExpBaseTwo(x : real) return real; + function NextPowerOfTwo(x : natural) return natural; + function NextExpBaseTwo(x : natural) return natural; + function GCD(a, b : natural) return natural; + function LCM(a, b : natural) return natural; + function UTILS_PERIOD_NS(f_in_MHz : real) return real; + function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural; + function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural; + function f_correct(f : real) return natural; + +end utils_pkg; + + +package body utils_pkg is + + ------------------------------------------------------------- + function MIN (X, Y: INTEGER) return INTEGER is + variable res : integer := X; + begin + if Y < X then + res := Y; + end if; + + return res; + + end MIN; + + ------------------------------------------------------------- + function MAX (X, Y: INTEGER) return INTEGER is + variable res : integer := X; + begin + if Y > X then + res := Y; + end if; + + return res; + + end MAX; + + ------------------------------------------------------------- + function NextExpBaseTwo(x : real) return real is + begin + return ceil(log2(x)); + end NextExpBaseTwo; + + ------------------------------------------------------------- + function NextPowerOfTwo(x : real) return real is + begin + + return 2.0**NextExpBaseTwo(x); + end NextPowerOfTwo; + + ------------------------------------------------------------- + function NextExpBaseTwo(x : natural) return natural is + begin + return natural(NextExpBaseTwo(real(x))); + end NextExpBaseTwo; + + ------------------------------------------------------------- + function NextPowerOfTwo(x : natural) return natural is + begin + + return 2**NextExpBaseTwo(x); + end NextPowerOfTwo; + + ------------------------------------------------------------- + function GCD(a, b : natural) return natural is + variable aa : natural; + variable bb : natural; + begin + aa := a; + bb := b; + while bb /= 0 loop + if aa > bb then + aa := aa - bb; + else + bb := bb - aa; + end if; + end loop; + + return aa; + + end GCD; + + ------------------------------------------------------------- + function LCM(a, b : natural) return natural is + begin + + return (a * b)/GCD(a, b); + + end LCM; + + ------------------------------------------------------------- + function UTILS_PERIOD_NS(f_in_MHz : real) return real is + begin + + return 1.0E3/f_in_MHz; + + end UTILS_PERIOD_NS; + + ------------------------------------------------------------- + function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural is + variable f_in : natural; + variable f_out : natural; + variable C : natural; + variable M : natural; + variable D : natural; + begin + C := f_correct(f_out_MHz); + if C < 2 then + C := f_correct(f_in_MHz); + end if; + + f_out := natural(ceil(real(C)*f_out_MHz)); + f_in := natural(ceil(real(C)*f_in_MHz)); + + M := LCM(f_in, f_out)/f_in; + D := f_in/GCD(f_in, f_out); + + assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure; + + if M = 1 then + M := 2; + end if; + + return M; + + end UTILS_FREQ_M; + + ------------------------------------------------------------- + function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural is + variable f_in : natural; + variable f_out : natural; + variable C : natural; + variable M : natural; + variable D : natural; + begin + C := f_correct(f_out_MHz); + if C < 2 then + C := f_correct(f_in_MHz); + end if; + + f_out := natural(ceil(real(C)*f_out_MHz)); + f_in := natural(ceil(real(C)*f_in_MHz)); + + M := LCM(f_in, f_out)/f_in; + D := f_in/GCD(f_in, f_out); + + assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure; + + if M = 1 then + D := 2*D; + end if; + + return D; + + end UTILS_FREQ_D; + + ------------------------------------------------------------- + function f_correct(f : real) return natural is + constant MAX_ITER : positive := 100; + constant MAX_ERR : real := 0.01; + variable fpart : real; + variable err : real; + begin + for i in 1 to MAX_ITER loop + fpart := real(i)*f - ceil(real(i)*f); + err := abs(fpart); + if err < max_err then + return i; + end if; + end loop; + end f_correct; + + ------------------------------------------------------------- +end utils_pkg; + + diff --git a/lib/radio/ddc/src/syn_ddc.vhd b/lib/radio/ddc/src/syn_ddc.vhd index 751ca44..414dea3 100644 --- a/lib/radio/ddc/src/syn_ddc.vhd +++ b/lib/radio/ddc/src/syn_ddc.vhd @@ -1,419 +1,462 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 17:16:42 13.05.2007 --- Design Name: tb_nco --- Module Name: tb_nco.vhd --- Project Name: nco --- Target Device: --- Tool versions: --- Description: --- --------------------------------------------------------------------------------- -LIBRARY ieee; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.MATH_REAL.ALL; -USE ieee.numeric_std.ALL; - -library ieee_proposed; -use ieee_proposed.math_utility_pkg.all; -use ieee_proposed.fixed_pkg.all; - -library altera; -use altera.altera_syn_attributes.all; - -library work; -use work.fixed_util_pkg.all; - - ENTITY syn_ddc IS - Generic - ( - nbits_in : integer := 16; - nbits_in_frac : integer := 14; - nbits_out : integer := 32; - nbits_out_frac : integer := 30; - lo_nbits_phase : integer := 24; - lo_nbits_freq : integer := 24; - cic_nstages : integer := 5; - cic_ratio : integer := 25; - cic_scale_nbits : integer := 22 - ); - PORT - ( - rst : in std_logic; - - adc_clk : in std_logic; - adc_da : in signed(15 downto 0); - adc_ofa : in std_logic; - adc_rand : out std_logic; - adc_pga : out std_logic; - adc_dith : out std_logic; - adc_shdn : out std_logic; - - usb_usbclk : in std_logic; - usb_ifclk : in std_logic; - usb_fd : out signed(15 downto 0); - usb_pktend : out std_logic; - usb_fifoadr : out unsigned(1 downto 0); - usb_slcs_n : out std_logic; - usb_slwr_n : out std_logic; - usb_slrd_n : out std_logic; - usb_sloe : out std_logic; - usb_flaga : in std_logic; - usb_flagb : in std_logic; - usb_flagc : in std_logic; - - cl_clk_out : out std_logic; - cl_dout : out unsigned(23 downto 0); - cl_pat_sel : out std_logic; - cl_prbs_en : out std_logic; - cl_ds_opt : out std_logic; - cl_bal : out std_logic; - cl_pd_n : out std_logic; - cl_tsen : in std_logic; - - reg_aen : in std_logic; - reg_dio : inout unsigned(7 downto 0); - reg_oe : in std_logic; - reg_we : in std_logic - - ); - END syn_ddc; - -ARCHITECTURE behavior OF syn_ddc IS - - -- Component Declaration for the Unit Under Test (UUT) - COMPONENT ddc - GENERIC - ( - nbits_in : integer; - nbits_in_frac : integer; - nbits_out : integer; - nbits_out_frac : integer; - lo_nbits_phase : integer; - lo_nbits_freq : integer; - cic_nstages : integer; - cic_ratio : integer; - cic_scale_nbits : integer - ); - PORT - ( - rst : in std_logic; - clk : in std_logic; - lo_nco_rst : in std_logic; - lo_nco_en : in std_logic; - lo_freq_in : in unsigned(lo_nbits_freq-1 downto 0); - lo_phase_in : in unsigned(lo_nbits_phase-1 downto 0); - din_vld : in std_logic; - din_i : in sfixed; - din_q : in sfixed; - dec_vld : out std_logic; - dec_i : out sfixed; - dec_q : out sfixed; - dout_vld : out std_logic; - dout_i : out sfixed; - dout_q : out sfixed - ); - END COMPONENT; - - --Outputs - SIGNAL ddc_din_i : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); - SIGNAL ddc_din_q : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); - SIGNAL ddc_dout_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); - SIGNAL ddc_dout_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); - - SIGNAL dec_vld : std_logic; - SIGNAL ddc_dec_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); - SIGNAL ddc_dec_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); - - - SIGNAL reg_lo_nco_rst : std_logic; - SIGNAL reg_lo_nco_en : std_logic; - SIGNAL reg_lo_freq_in : unsigned(31 downto 0); - SIGNAL reg_lo_phase_in : unsigned(31 downto 0); - - SIGNAL reg_en_addr : std_logic; - SIGNAL reg_en_data : std_logic; - SIGNAL reg_addr_last : std_logic; - SIGNAL reg_data_last : std_logic; - SIGNAL reg_addr_async : unsigned (7 downto 0); - SIGNAL reg_data_async : unsigned (7 downto 0); - SIGNAL reg_addr : unsigned (7 downto 0); - SIGNAL reg_data : unsigned (7 downto 0); - - SIGNAL fifo_usb_we : std_logic; - SIGNAL fifo_usb_re : std_logic; - SIGNAL fifo_usb_ff : std_logic; - SIGNAL fifo_usb_ef : std_logic; - SIGNAL fifo_usb_aff : std_logic; - SIGNAL fifo_usb_aef : std_logic; - - type fifo_usb_array_t is array (0 to 3) of unsigned (15 downto 0); - SIGNAL fifo_usb_in : fifo_usb_array_t; - SIGNAL fifo_usb_out : unsigned (15 downto 0); - - SIGNAL fifo_usb_we_pipe : unsigned(3 downto 0); - SIGNAL enable : std_logic; - SIGNAL ddc_din_vld : std_logic; - SIGNAL ddc_dout_vld : std_logic; - - SIGNAL cl_we_pipe : unsigned(1 downto 0); - type cl_data_array_t is array (0 to 1) of unsigned (31 downto 0); - SIGNAL cl_sd_data : cl_data_array_t; - - SIGNAL cl_dout_L : std_logic_vector(24 downto 0); - SIGNAL cl_dout_H : std_logic_vector(24 downto 0); - SIGNAL cl_dout_clk : std_logic_vector(24 downto 0); - -BEGIN - - -- Instantiate the Unit Under Test (UUT) - inst_ddc : ddc - GENERIC MAP - ( - nbits_in => nbits_in, - nbits_in_frac => nbits_in_frac, - nbits_out => nbits_out, - nbits_out_frac => nbits_out_frac, - lo_nbits_phase => lo_nbits_phase, - lo_nbits_freq => lo_nbits_freq, - cic_nstages => cic_nstages, - cic_ratio => cic_ratio, - cic_scale_nbits => cic_scale_nbits - ) - PORT MAP - ( - rst => rst, - clk => adc_clk, - lo_nco_rst => reg_lo_nco_rst, - lo_nco_en => reg_lo_nco_en, - lo_freq_in => reg_lo_freq_in(lo_nbits_freq-1 downto 0), - lo_phase_in => reg_lo_phase_in(lo_nbits_phase-1 downto 0), - din_vld => ddc_din_vld, - din_i => ddc_din_i, - din_q => ddc_din_q, - dec_vld => dec_vld, - dec_i => ddc_dec_i, - dec_q => ddc_dec_q, - dout_vld => ddc_dout_vld, - dout_i => ddc_dout_i, - dout_q => ddc_dout_q - ); - -reg_dio <= reg_addr when reg_oe = '1' else (others => 'Z'); - ----------------------------------------------------------- --- Register control ----------------------------------------------------------- -proc_reg_da_async: - process(reg_we) - begin - if rising_edge(reg_we) then - if reg_aen = '1' then - reg_addr_async <= reg_dio; - else - reg_data_async <= reg_dio; - end if; - end if; - end process; - -proc_reg_da_sync: - process(adc_clk) --- process(usb_usbclk) - begin - if rising_edge(adc_clk) then --- if rising_edge(usb_usbclk) then - if rst = '1' then - reg_en_addr <= '0'; - reg_en_data <= '0'; - reg_addr_last <= '0'; - reg_data_last <= '0'; - elsif reg_we = '1' then - reg_en_addr <= reg_aen and not reg_addr_last; - reg_en_data <= not (reg_aen or reg_data_last); - reg_addr_last <= reg_aen; - reg_data_last <= not reg_aen; - else - reg_addr_last <= '0'; - reg_data_last <= '0'; - end if; - reg_data <= reg_data_async; - reg_addr <= reg_addr_async; - end if; - end process; - - -- Registers -proc_register_write: - process(adc_clk) --- process(usb_usbclk) - begin - if rising_edge(adc_clk) then --- if rising_edge(usb_usbclk) then - if rst = '1' then - reg_lo_nco_rst <= '0'; - reg_lo_nco_en <= '0'; - elsif reg_en_data = '1' then - case reg_addr is - when X"00" => -- Control - reg_lo_nco_rst <= reg_data(0); - reg_lo_nco_en <= reg_data(1); - - when X"10" => -- freqency - reg_lo_freq_in(7 downto 0) <= reg_data; - - when X"11" => -- freqency - reg_lo_freq_in(15 downto 8) <= reg_data; - - when X"12" => -- freqency - reg_lo_freq_in(23 downto 16) <= reg_data; - - when X"13" => -- freqency - reg_lo_freq_in(31 downto 24) <= reg_data; - - when X"20" => -- phase - reg_lo_phase_in(7 downto 0) <= reg_data; - - when X"21" => -- phase - reg_lo_phase_in(15 downto 8) <= reg_data; - - when X"22" => -- phase - reg_lo_phase_in(23 downto 16) <= reg_data; - - when X"23" => -- phase - reg_lo_phase_in(31 downto 24) <= reg_data; - - when others => null; - end case; - end if; - end if; - end process; - ----------------------------------------------------------- --- DDC input ----------------------------------------------------------- -proc_adc_input_register: - process(adc_clk) - begin - if rising_edge(adc_clk) then - ddc_din_vld <= enable; - if enable = '1' then - ddc_din_i <= sfixed(resize(adc_da, nbits_in)); - end if; - end if; - end process; - - ddc_din_q <= to_sfixed(0.0, shi(nbits_in, nbits_in_frac), slo(nbits_in, nbits_in_frac)); - - enable <= '1'; - adc_rand <= '0'; - adc_pga <= '0'; - adc_dith <= '0'; - adc_shdn <= not enable; - ----------------------------------------------------------- --- USB FIFO output ----------------------------------------------------------- -proc_usb_interleave_iq: - process(adc_clk) - variable i, q : unsigned(31 downto 0); - begin - if rising_edge(adc_clk) then - if rst = '1' then - fifo_usb_we_pipe <= (others => '0'); - elsif ddc_dout_vld = '1' then - fifo_usb_we_pipe <= (others => '1'); - i := unsigned(ddc_dout_i); - q := unsigned(ddc_dout_q); - fifo_usb_in(0) <= i(15 downto 0); - fifo_usb_in(1) <= i(31 downto 16); - fifo_usb_in(2) <= q(15 downto 0); - fifo_usb_in(3) <= q(31 downto 16); - elsif fifo_usb_ff = '0' then - fifo_usb_we_pipe <= fifo_usb_we_pipe(fifo_usb_we_pipe'left-1 downto 0) & '0'; - fifo_usb_in(0) <= fifo_usb_in(1); - fifo_usb_in(1) <= fifo_usb_in(2); - fifo_usb_in(2) <= fifo_usb_in(3); - end if; - end if; - end process; - -inst_usbfifo: entity work.fifo_async - GENERIC MAP - ( - addr_width => 7, - data_width => 16, - almost_full_thresh => 96, - almost_empty_thresh => 32 - ) - PORT MAP - ( - rst => rst, - clk_w => adc_clk, - clk_r => usb_ifclk, - we => fifo_usb_we, - re => fifo_usb_re, - data_w => fifo_usb_in(0), - data_r => fifo_usb_out, - fifo_full => fifo_usb_ff, - fifo_empty => fifo_usb_ef, - fifo_afull => fifo_usb_aff, - fifo_aempty => fifo_usb_aef - - ); - - fifo_usb_we <= fifo_usb_we_pipe(fifo_usb_we_pipe'left); - usb_fd <= signed(fifo_usb_out); - fifo_usb_re <= usb_flaga; - usb_slcs_n <= '0'; - usb_slwr_n <= not usb_flaga; - usb_slrd_n <= '1'; - usb_sloe <= '0'; - - ----------------------------------------------------------- --- Channel-Link DDR output ----------------------------------------------------------- -proc_cl_interleave_iq: - process(adc_clk) - variable i, q : unsigned(31 downto 0); - begin - if rising_edge(adc_clk) then - if rst = '1' then - cl_we_pipe <= (others => '0'); - elsif ddc_dout_vld = '1' then - cl_we_pipe <= (others => '1'); - i := unsigned(ddc_dout_i); - q := unsigned(ddc_dout_q); - cl_sd_data(0) <= i; - cl_sd_data(1) <= q; - else - cl_we_pipe <= cl_we_pipe(cl_we_pipe'left-1 downto 0) & '0'; - cl_sd_data(0) <= cl_sd_data(1); - end if; - end if; - end process; - -inst_cl_ddr_out: entity work.cl_ddr_out - PORT MAP - ( - aclr => rst, - datain_h => cl_dout_H, - datain_l => cl_dout_L, - outclock => adc_clk, - outclocken => '1', - dataout => cl_dout_clk - ); - - cl_dout_H <= '0' & cl_we_pipe(cl_we_pipe'left) & "0000000" & std_logic_vector(cl_sd_data(0)(31 downto 16)); - cl_dout_L <= '1' & cl_we_pipe(cl_we_pipe'left) & "0000000" & std_logic_vector(cl_sd_data(0)(15 downto 0)); - cl_dout <= unsigned(cl_dout_clk(23 downto 0)); - cl_clk_out <= cl_dout_clk(24); - cl_pat_sel <= '0'; - cl_prbs_en <= '0'; - cl_ds_opt <= '0'; - cl_bal <= '0'; - cl_pd_n <= '1'; - ----------------------------------------------------------- -END; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:16:42 13.05.2007 +-- Design Name: tb_nco +-- Module Name: tb_nco.vhd +-- Project Name: nco +-- Target Device: +-- Tool versions: +-- Description: +-- +-------------------------------------------------------------------------------- +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.MATH_REAL.ALL; +USE ieee.numeric_std.ALL; + +library ieee_proposed; +use ieee_proposed.math_utility_pkg.all; +use ieee_proposed.fixed_pkg.all; + +--library altera; +--use altera.altera_syn_attributes.all; + +library work; +use work.fixed_util_pkg.all; + + ENTITY syn_ddc IS + Generic + ( + nbits_in : integer := 16; + nbits_in_frac : integer := 14; + nbits_out : integer := 32; + nbits_out_frac : integer := 30; + lo_nbits_phase : integer := 24; + lo_nbits_freq : integer := 24; + cic_nstages : integer := 5; + cic_ratio : integer := 25; + cic_scale_nbits : integer := 22 + ); + PORT + ( + rst : in std_logic; + + adc_clk : in std_logic; + adc_da : in signed(15 downto 0); + adc_ofa : in std_logic; + adc_rand : out std_logic; + adc_pga : out std_logic; + adc_dith : out std_logic; + adc_shdn : out std_logic; + + usb_usbclk : in std_logic; + usb_ifclk : in std_logic; + usb_fd : out signed(15 downto 0); + usb_pktend : out std_logic; + usb_fifoadr : out unsigned(1 downto 0); + usb_slcs_n : out std_logic; + usb_slwr_n : out std_logic; + usb_slrd_n : out std_logic; + usb_sloe : out std_logic; + usb_flaga : in std_logic; + usb_flagb : in std_logic; + usb_flagc : in std_logic; + + cl_clk_out : out std_logic; + cl_dout : out unsigned(20 downto 0); + cl_pd_n : out std_logic; + + reg_aen : in std_logic; + reg_dio : inout unsigned(7 downto 0); + reg_oe : in std_logic; + reg_we : in std_logic + + ); + END syn_ddc; + +ARCHITECTURE behavior OF syn_ddc IS + + -- Component Declaration for the Unit Under Test (UUT) + COMPONENT ddc + GENERIC + ( + nbits_in : integer; + nbits_in_frac : integer; + nbits_out : integer; + nbits_out_frac : integer; + lo_nbits_phase : integer; + lo_nbits_freq : integer; + cic_nstages : integer; + cic_ratio : integer; + cic_scale_nbits : integer + ); + PORT + ( + rst : in std_logic; + clk : in std_logic; + lo_nco_rst : in std_logic; + lo_nco_en : in std_logic; + lo_freq_in : in unsigned(lo_nbits_freq-1 downto 0); + lo_phase_in : in unsigned(lo_nbits_phase-1 downto 0); + din_vld : in std_logic; + din_i : in sfixed; + din_q : in sfixed; + dec_vld : out std_logic; + dec_i : out sfixed; + dec_q : out sfixed; + dout_vld : out std_logic; + dout_i : out sfixed; + dout_q : out sfixed + ); + END COMPONENT; + + --Outputs + SIGNAL ddc_din_i : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); + SIGNAL ddc_din_q : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); + SIGNAL ddc_dout_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); + SIGNAL ddc_dout_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); + + SIGNAL dec_vld : std_logic; + SIGNAL ddc_dec_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); + SIGNAL ddc_dec_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); + + + SIGNAL reg_lo_nco_rst : std_logic; + SIGNAL reg_lo_nco_en : std_logic; + SIGNAL reg_lo_freq_in : unsigned(31 downto 0); + SIGNAL reg_lo_phase_in : unsigned(31 downto 0); + + SIGNAL reg_en_addr : std_logic; + SIGNAL reg_en_data : std_logic; + SIGNAL reg_addr_last : std_logic; + SIGNAL reg_data_last : std_logic; + SIGNAL reg_addr_async : unsigned (7 downto 0); + SIGNAL reg_data_async : unsigned (7 downto 0); + SIGNAL reg_addr : unsigned (7 downto 0); + SIGNAL reg_data : unsigned (7 downto 0); + + SIGNAL fifo_usb_we : std_logic; + SIGNAL fifo_usb_re : std_logic; + SIGNAL fifo_usb_ff : std_logic; + SIGNAL fifo_usb_ef : std_logic; + SIGNAL fifo_usb_aff : std_logic; + SIGNAL fifo_usb_aef : std_logic; + + type fifo_usb_array_t is array (0 to 3) of unsigned (15 downto 0); + SIGNAL fifo_usb_in : fifo_usb_array_t; + SIGNAL fifo_usb_out : unsigned (15 downto 0); + + SIGNAL cl_clk : std_logic; + SIGNAL fifo_cl_we : std_logic; + SIGNAL fifo_cl_re : std_logic; + SIGNAL fifo_cl_ff : std_logic; + SIGNAL fifo_cl_ef : std_logic; + SIGNAL fifo_cl_aff : std_logic; + SIGNAL fifo_cl_aef : std_logic; + + SIGNAL fifo_cl_in : unsigned (63 downto 0); + SIGNAL fifo_cl_out : unsigned (63 downto 0); + + SIGNAL fifo_usb_we_pipe : unsigned(3 downto 0); + SIGNAL enable : std_logic; + SIGNAL ddc_din_vld : std_logic; + SIGNAL ddc_dout_vld : std_logic; + + SIGNAL cl_rst_pipe : unsigned (63 downto 0); + SIGNAL cl_rst : std_logic; + SIGNAL cl_phase : unsigned(1 downto 0); + SIGNAL cl_data : unsigned(20 downto 0); + subtype cl_clkgen_cnt_t is natural range 0 to (2*cic_ratio/2/5)-1; + SIGNAL cl_clkgen_cnt : cl_clkgen_cnt_t; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + inst_ddc : ddc + GENERIC MAP + ( + nbits_in => nbits_in, + nbits_in_frac => nbits_in_frac, + nbits_out => nbits_out, + nbits_out_frac => nbits_out_frac, + lo_nbits_phase => lo_nbits_phase, + lo_nbits_freq => lo_nbits_freq, + cic_nstages => cic_nstages, + cic_ratio => cic_ratio, + cic_scale_nbits => cic_scale_nbits + ) + PORT MAP + ( + rst => rst, + clk => adc_clk, + lo_nco_rst => reg_lo_nco_rst, + lo_nco_en => reg_lo_nco_en, + lo_freq_in => reg_lo_freq_in(lo_nbits_freq-1 downto 0), + lo_phase_in => reg_lo_phase_in(lo_nbits_phase-1 downto 0), + din_vld => ddc_din_vld, + din_i => ddc_din_i, + din_q => ddc_din_q, + dec_vld => dec_vld, + dec_i => ddc_dec_i, + dec_q => ddc_dec_q, + dout_vld => ddc_dout_vld, + dout_i => ddc_dout_i, + dout_q => ddc_dout_q + ); + +reg_dio <= reg_addr when reg_oe = '1' else (others => 'Z'); + +---------------------------------------------------------- +-- Register control +---------------------------------------------------------- +proc_reg_da_async: + process(reg_we) + begin + if rising_edge(reg_we) then + if reg_aen = '1' then + reg_addr_async <= reg_dio; + else + reg_data_async <= reg_dio; + end if; + end if; + end process; + +proc_reg_da_sync: + process(adc_clk) +-- process(usb_usbclk) + begin + if rising_edge(adc_clk) then +-- if rising_edge(usb_usbclk) then + if rst = '1' then + reg_en_addr <= '0'; + reg_en_data <= '0'; + reg_addr_last <= '0'; + reg_data_last <= '0'; + elsif reg_we = '1' then + reg_en_addr <= reg_aen and not reg_addr_last; + reg_en_data <= not (reg_aen or reg_data_last); + reg_addr_last <= reg_aen; + reg_data_last <= not reg_aen; + else + reg_addr_last <= '0'; + reg_data_last <= '0'; + end if; + reg_data <= reg_data_async; + reg_addr <= reg_addr_async; + end if; + end process; + + -- Registers +proc_register_write: + process(adc_clk) +-- process(usb_usbclk) + begin + if rising_edge(adc_clk) then +-- if rising_edge(usb_usbclk) then + if rst = '1' then + reg_lo_nco_rst <= '1'; + reg_lo_nco_en <= '0'; + elsif reg_en_data = '1' then + case reg_addr is + when X"00" => -- Control + reg_lo_nco_rst <= reg_data(0); + reg_lo_nco_en <= reg_data(1); + + when X"10" => -- freqency + reg_lo_freq_in(7 downto 0) <= reg_data; + + when X"11" => -- freqency + reg_lo_freq_in(15 downto 8) <= reg_data; + + when X"12" => -- freqency + reg_lo_freq_in(23 downto 16) <= reg_data; + + when X"13" => -- freqency + reg_lo_freq_in(31 downto 24) <= reg_data; + + when X"20" => -- phase + reg_lo_phase_in(7 downto 0) <= reg_data; + + when X"21" => -- phase + reg_lo_phase_in(15 downto 8) <= reg_data; + + when X"22" => -- phase + reg_lo_phase_in(23 downto 16) <= reg_data; + + when X"23" => -- phase + reg_lo_phase_in(31 downto 24) <= reg_data; + + when others => null; + end case; + end if; + end if; + end process; + +---------------------------------------------------------- +-- DDC input +---------------------------------------------------------- +proc_adc_input_register: + process(adc_clk) + begin + if rising_edge(adc_clk) then + ddc_din_i <= sfixed(resize(adc_da, nbits_in)); + ddc_din_vld <= reg_lo_nco_en; + end if; + end process; + + ddc_din_q <= to_sfixed(0.0, shi(nbits_in, nbits_in_frac), slo(nbits_in, nbits_in_frac)); + + adc_rand <= '0'; + adc_pga <= '0'; + adc_dith <= '0'; + adc_shdn <= not reg_lo_nco_en; + +---------------------------------------------------------- +-- USB FIFO output +---------------------------------------------------------- +proc_usb_interleave_iq: + process(adc_clk) + variable i, q : unsigned(31 downto 0); + begin + if rising_edge(adc_clk) then + if rst = '1' then + fifo_usb_we_pipe <= (others => '0'); + elsif ddc_dout_vld = '1' then + fifo_usb_we_pipe <= (others => '1'); + i := to_unsigned(ufixed(ddc_dout_i)); + q := to_unsigned(ufixed(ddc_dout_q)); + fifo_usb_in(0) <= i(15 downto 0); + fifo_usb_in(1) <= i(31 downto 16); + fifo_usb_in(2) <= q(15 downto 0); + fifo_usb_in(3) <= q(31 downto 16); + elsif fifo_usb_ff = '0' then + fifo_usb_we_pipe <= fifo_usb_we_pipe(fifo_usb_we_pipe'left-1 downto 0) & '0'; + fifo_usb_in(0) <= fifo_usb_in(1); + fifo_usb_in(1) <= fifo_usb_in(2); + fifo_usb_in(2) <= fifo_usb_in(3); + end if; + end if; + end process; + +inst_usbfifo: entity work.fifo_async + GENERIC MAP + ( + addr_width => 7, + data_width => 16, + almost_full_thresh => 96, + almost_empty_thresh => 32 + ) + PORT MAP + ( + rst => rst, + clk_w => adc_clk, + clk_r => usb_ifclk, + we => fifo_usb_we, + re => fifo_usb_re, + data_w => fifo_usb_in(0), + data_r => fifo_usb_out, + fifo_full => fifo_usb_ff, + fifo_empty => fifo_usb_ef, + fifo_afull => fifo_usb_aff, + fifo_aempty => fifo_usb_aef + + ); + + fifo_usb_we <= fifo_usb_we_pipe(fifo_usb_we_pipe'left); + usb_fd <= signed(fifo_usb_out); + fifo_usb_re <= usb_flaga; + usb_slcs_n <= '0'; + usb_slwr_n <= not usb_flaga; + usb_slrd_n <= '1'; + usb_sloe <= '0'; + + +---------------------------------------------------------- +-- Channel-Link output +---------------------------------------------------------- +inst_cl_fifo: entity work.fifo_async + GENERIC MAP + ( + addr_width => 4, + data_width => 64, + almost_full_thresh => 96, + almost_empty_thresh => 32 + ) + PORT MAP + ( + rst => rst, + clk_w => adc_clk, + clk_r => cl_clk, + we => fifo_cl_we, + re => fifo_cl_re, + data_w => fifo_cl_in, + data_r => fifo_cl_out, + fifo_full => fifo_cl_ff, + fifo_empty => fifo_cl_ef, + fifo_afull => fifo_cl_aff, + fifo_aempty => fifo_cl_aef + + ); + + fifo_cl_in <= to_unsigned(ufixed(ddc_dout_i)) & to_unsigned(ufixed(ddc_dout_i)); + fifo_cl_we <= ddc_dout_vld; + fifo_cl_re <= '1'; + +proc_cl_clkgen: + process(adc_clk) + begin + if rising_edge(adc_clk) then + if rst = '1' then + cl_rst_pipe <= (others => '1'); + cl_clkgen_cnt <= cl_clkgen_cnt_t'high; + cl_clk <= '0'; + else + if cl_clkgen_cnt = 0 then + cl_clkgen_cnt <= cl_clkgen_cnt_t'high; + cl_clk <= not cl_clk; + cl_rst_pipe <= cl_rst_pipe(cl_rst_pipe'left-1 downto 0) & '0'; + else + cl_clkgen_cnt <= cl_clkgen_cnt - 1; + end if; + end if; + end if; + end process; + + cl_rst <= cl_rst_pipe(cl_rst_pipe'left); + +proc_cl_interleave_iq: + process(cl_clk) + variable i, q : unsigned(31 downto 0); + begin + if rising_edge(cl_clk) then + if cl_rst = '1' then + cl_phase <= (others => '0'); + else + i := fifo_cl_out(31 downto 0); + q := fifo_cl_out(63 downto 32); + if cl_phase(1) = '0' then + if cl_phase(0) = '0' then + cl_data <= not fifo_cl_ef & cl_phase & "00" & i(15 downto 0); + else + cl_data <= not fifo_cl_ef & cl_phase & "00" & i(31 downto 16); + end if; + else + if cl_phase(0) = '0' then + cl_data <= not fifo_cl_ef & cl_phase & "00" & q(15 downto 0); + else + cl_data <= not fifo_cl_ef & cl_phase & "00" & q(31 downto 16); + end if; + end if; + cl_phase <= cl_phase + 1; + end if; + end if; + end process; + + cl_dout <= cl_data; + cl_clk_out <= cl_clk; + cl_pd_n <= not cl_rst; + +---------------------------------------------------------- +END; diff --git a/lib/rams/dpram_1w1r2c_ra_sim.vhd b/lib/rams/dpram_1w1r2c_ra_sim.vhd index 7b44736..fa44e85 100644 --- a/lib/rams/dpram_1w1r2c_ra_sim.vhd +++ b/lib/rams/dpram_1w1r2c_ra_sim.vhd @@ -1,82 +1,82 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered address - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_1w1r2c_ra_sim.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c_ra is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c_ra; - -architecture Behavioral of dpram_1w1r2c_ra is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - signal addr_b_r : unsigned (addr_width-1 downto 0); - -begin - - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered address + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_1w1r2c_ra_sim.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c_ra is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c_ra; + +architecture Behavioral of dpram_1w1r2c_ra is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + signal addr_b_r : unsigned (addr_width-1 downto 0); + +begin + + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/rams/dpram_1w1r2c_ra_xil.vhd b/lib/rams/dpram_1w1r2c_ra_xil.vhd index 8c0b54b..ff10f8c 100644 --- a/lib/rams/dpram_1w1r2c_ra_xil.vhd +++ b/lib/rams/dpram_1w1r2c_ra_xil.vhd @@ -1,82 +1,82 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered address - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_1w1r2c_ra_xil.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c_ra is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c_ra; - -architecture Behavioral of dpram_1w1r2c_ra is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - signal addr_b_r : unsigned (addr_width-1 downto 0); - -begin - - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered address + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_1w1r2c_ra_xil.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c_ra is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c_ra; + +architecture Behavioral of dpram_1w1r2c_ra is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + signal addr_b_r : unsigned (addr_width-1 downto 0); + +begin + + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/rams/dpram_1w1r2c_ro_sim.vhd b/lib/rams/dpram_1w1r2c_ro_sim.vhd index d549f16..4e6fd30 100644 --- a/lib/rams/dpram_1w1r2c_ro_sim.vhd +++ b/lib/rams/dpram_1w1r2c_ro_sim.vhd @@ -1,80 +1,80 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered output - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_1w1r2c_ro_sim.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c_ro is - Generic ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c_ro; - -architecture Behavioral of dpram_1w1r2c_ro is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - dout_b <= RAM(to_integer(addr_b)); - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered output + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_1w1r2c_ro_sim.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c_ro is + Generic ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c_ro; + +architecture Behavioral of dpram_1w1r2c_ro is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + dout_b <= RAM(to_integer(addr_b)); + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/rams/dpram_1w1r2c_ro_xil.vhd b/lib/rams/dpram_1w1r2c_ro_xil.vhd index 32e4b42..76533dc 100644 --- a/lib/rams/dpram_1w1r2c_ro_xil.vhd +++ b/lib/rams/dpram_1w1r2c_ro_xil.vhd @@ -1,81 +1,81 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered output - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_1w1r2c_ro_xil.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -entity dpram_1w1r2c_ro is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_1w1r2c_ro; - -architecture Behavioral of dpram_1w1r2c_ro is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - -process (clk_a) - begin - if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - end if; - end if; - end if; -end process; - -process (clk_b) - begin - if clk_b'event and clk_b = '1' then - if en_b = '1' then - dout_b <= RAM(to_integer(addr_b)); - end if; - end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 1 write, 1 read, 2 clocks, registered output + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_1w1r2c_ro_xil.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +entity dpram_1w1r2c_ro is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_1w1r2c_ro; + +architecture Behavioral of dpram_1w1r2c_ro is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + +process (clk_a) + begin + if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + end if; + end if; + end if; +end process; + +process (clk_b) + begin + if clk_b'event and clk_b = '1' then + if en_b = '1' then + dout_b <= RAM(to_integer(addr_b)); + end if; + end if; +end process; + + +end Behavioral; + diff --git a/lib/rams/dpram_2w2r2c_ra_sim.vhd b/lib/rams/dpram_2w2r2c_ra_sim.vhd index 1d860c7..c96138c 100644 --- a/lib/rams/dpram_2w2r2c_ra_sim.vhd +++ b/lib/rams/dpram_2w2r2c_ra_sim.vhd @@ -1,95 +1,95 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered address - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_2w2r2c_ra_sim.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c_ra is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c_ra; - -architecture Behavioral of dpram_2w2r2c_ra is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - signal RAM : RAMtype; - -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a, clk_b) -begin - if clk_a'event and clk_a = '1' and en_a = '1' and we_a = '1' then - RAM(to_integer(addr_a)) <= din_a; - elsif clk_b'event and clk_b = '1' and en_b = '1' and we_b = '1' then - RAM(to_integer(addr_b)) <= din_b; - end if; -end process; - -process (clk_a) -begin - if clk_a'event and clk_a = '1' then - if en_a = '1' then - addr_a_r <= addr_a; - end if; - end if; -end process; - -process (clk_b) -begin - if clk_b'event and clk_b = '1' then - if en_b = '1' then - addr_b_r <= addr_b; - end if; - end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered address + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_2w2r2c_ra_sim.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c_ra is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c_ra; + +architecture Behavioral of dpram_2w2r2c_ra is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + signal RAM : RAMtype; + +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a, clk_b) +begin + if clk_a'event and clk_a = '1' and en_a = '1' and we_a = '1' then + RAM(to_integer(addr_a)) <= din_a; + elsif clk_b'event and clk_b = '1' and en_b = '1' and we_b = '1' then + RAM(to_integer(addr_b)) <= din_b; + end if; +end process; + +process (clk_a) +begin + if clk_a'event and clk_a = '1' then + if en_a = '1' then + addr_a_r <= addr_a; + end if; + end if; +end process; + +process (clk_b) +begin + if clk_b'event and clk_b = '1' then + if en_b = '1' then + addr_b_r <= addr_b; + end if; + end if; +end process; + +end Behavioral; + diff --git a/lib/rams/dpram_2w2r2c_ra_xil.vhd b/lib/rams/dpram_2w2r2c_ra_xil.vhd index 8847b0b..53b18fb 100644 --- a/lib/rams/dpram_2w2r2c_ra_xil.vhd +++ b/lib/rams/dpram_2w2r2c_ra_xil.vhd @@ -1,93 +1,93 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered address - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_2w2r2c_ra_xil.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c_ra is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c_ra; - -architecture Behavioral of dpram_2w2r2c_ra is - - constant depth : integer := 2**addr_width; - signal addr_a_r : unsigned (addr_width-1 downto 0); - signal addr_b_r : unsigned (addr_width-1 downto 0); - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - shared variable RAM : RAMtype; - -begin - - dout_a <= RAM(to_integer(addr_a_r)); - dout_b <= RAM(to_integer(addr_b_r)); - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) := din_a; - end if; - addr_a_r <= addr_a; - end if; -end if; -end process; - - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) := din_b; - end if; - addr_b_r <= addr_b; - end if; -end if; -end process; - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered address + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_2w2r2c_ra_xil.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c_ra is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c_ra; + +architecture Behavioral of dpram_2w2r2c_ra is + + constant depth : integer := 2**addr_width; + signal addr_a_r : unsigned (addr_width-1 downto 0); + signal addr_b_r : unsigned (addr_width-1 downto 0); + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + shared variable RAM : RAMtype; + +begin + + dout_a <= RAM(to_integer(addr_a_r)); + dout_b <= RAM(to_integer(addr_b_r)); + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) := din_a; + end if; + addr_a_r <= addr_a; + end if; +end if; +end process; + + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) := din_b; + end if; + addr_b_r <= addr_b; + end if; +end if; +end process; + +end Behavioral; + diff --git a/lib/rams/dpram_2w2r2c_ro_sim.vhd b/lib/rams/dpram_2w2r2c_ro_sim.vhd index 79203ba..3c69b8b 100644 --- a/lib/rams/dpram_2w2r2c_ro_sim.vhd +++ b/lib/rams/dpram_2w2r2c_ro_sim.vhd @@ -1,88 +1,88 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered output - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_2w2r2c_ro_sim.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c_ro is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c_ro; - -architecture Behavioral of dpram_2w2r2c_ro is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - shared variable RAM : RAMtype; - -begin - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) := din_a; - end if; - dout_a <= RAM(to_integer(addr_a)); - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) := din_b; - end if; - dout_b <= RAM(to_integer(addr_b)); - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered output + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_2w2r2c_ro_sim.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c_ro is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c_ro; + +architecture Behavioral of dpram_2w2r2c_ro is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + shared variable RAM : RAMtype; + +begin + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) := din_a; + end if; + dout_a <= RAM(to_integer(addr_a)); + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) := din_b; + end if; + dout_b <= RAM(to_integer(addr_b)); + end if; +end if; +end process; + + +end Behavioral; + diff --git a/lib/rams/dpram_2w2r2c_ro_xil.vhd b/lib/rams/dpram_2w2r2c_ro_xil.vhd index 664a144..d30fd2b 100644 --- a/lib/rams/dpram_2w2r2c_ro_xil.vhd +++ b/lib/rams/dpram_2w2r2c_ro_xil.vhd @@ -1,88 +1,88 @@ -------------------------------------------------------------------------- --- Project: Dual-Port RAM with 1 clock latency for simulation --- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered output - --- 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 - ------------------------------------------------------------------------ --- $Header: /tmp/cvsroot/VHDL/lib/rams/dpram_2w2r2c_ro_xil.vhd,v 1.1 2013-02-09 09:27:21 jens Exp $ ------------------------------------------------------------------------ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.numeric_std.ALL; - -entity dpram_2w2r2c_ro is - Generic - ( - addr_width : integer := 3; - data_width : integer := 8 - ); - Port - ( - clk_a : in STD_LOGIC; - clk_b : in STD_LOGIC; - en_a : in STD_LOGIC; - en_b : in STD_LOGIC; - we_a : in STD_LOGIC; - we_b : in STD_LOGIC; - addr_a : in unsigned (addr_width-1 downto 0); - addr_b : in unsigned (addr_width-1 downto 0); - din_a : in unsigned (data_width-1 downto 0); - din_b : in unsigned (data_width-1 downto 0); - dout_a : out unsigned (data_width-1 downto 0); - dout_b : out unsigned (data_width-1 downto 0) - ); -end dpram_2w2r2c_ro; - -architecture Behavioral of dpram_2w2r2c_ro is - - constant depth : integer := 2**addr_width; - type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); - shared variable RAM : RAMtype; - -begin - -process (clk_a) -begin -if clk_a'event and clk_a = '1' then - if en_a = '1' then - if we_a = '1' then - RAM(to_integer(addr_a)) := din_a; - end if; - dout_a <= RAM(to_integer(addr_a)); - end if; -end if; -end process; - -process (clk_b) -begin -if clk_b'event and clk_b = '1' then - if en_b = '1' then - if we_b = '1' then - RAM(to_integer(addr_b)) := din_b; - end if; - dout_b <= RAM(to_integer(addr_b)); - end if; -end if; -end process; - - -end Behavioral; - +------------------------------------------------------------------------- +-- Project: Dual-Port RAM with 1 clock latency for simulation +-- This file: Dual-Port RAM 2 write, 2 read, 2 clocks, registered output + +-- 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 + +----------------------------------------------------------------------- +-- $Header: D:\usr\cvsroot/VHDL/lib/rams/dpram_2w2r2c_ro_xil.vhd,v 1.1 2013/02/09 09:27:21 jens Exp $ +----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +entity dpram_2w2r2c_ro is + Generic + ( + addr_width : integer := 3; + data_width : integer := 8 + ); + Port + ( + clk_a : in STD_LOGIC; + clk_b : in STD_LOGIC; + en_a : in STD_LOGIC; + en_b : in STD_LOGIC; + we_a : in STD_LOGIC; + we_b : in STD_LOGIC; + addr_a : in unsigned (addr_width-1 downto 0); + addr_b : in unsigned (addr_width-1 downto 0); + din_a : in unsigned (data_width-1 downto 0); + din_b : in unsigned (data_width-1 downto 0); + dout_a : out unsigned (data_width-1 downto 0); + dout_b : out unsigned (data_width-1 downto 0) + ); +end dpram_2w2r2c_ro; + +architecture Behavioral of dpram_2w2r2c_ro is + + constant depth : integer := 2**addr_width; + type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0); + shared variable RAM : RAMtype; + +begin + +process (clk_a) +begin +if clk_a'event and clk_a = '1' then + if en_a = '1' then + if we_a = '1' then + RAM(to_integer(addr_a)) := din_a; + end if; + dout_a <= RAM(to_integer(addr_a)); + end if; +end if; +end process; + +process (clk_b) +begin +if clk_b'event and clk_b = '1' then + if en_b = '1' then + if we_b = '1' then + RAM(to_integer(addr_b)) := din_b; + end if; + dout_b <= RAM(to_integer(addr_b)); + end if; +end if; +end process; + + +end Behavioral; + diff --git a/projects/mips_sys/sim/tb_mips_sys.fdo b/projects/mips_sys/sim/tb_mips_sys.fdo index 6535215..5cfecfa 100644 --- a/projects/mips_sys/sim/tb_mips_sys.fdo +++ b/projects/mips_sys/sim/tb_mips_sys.fdo @@ -37,7 +37,7 @@ vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_dcache.vhd" vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_icache.vhd" vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_biu.vhd" vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_top.vhd" -vcom -explicit -93 "../src/bootloader.ROM.vhd" +vcom -explicit -93 "../src/bootloader_flash.ROM.vhd" vcom -explicit -93 "../../../lib/misc/rom_wb.vhd" # VGA diff --git a/projects/mips_sys/src/tb_mips_sys.vhd b/projects/mips_sys/src/tb_mips_sys.vhd index c3a0bca..587d784 100644 --- a/projects/mips_sys/src/tb_mips_sys.vhd +++ b/projects/mips_sys/src/tb_mips_sys.vhd @@ -42,6 +42,8 @@ ARCHITECTURE behavior OF tb_mips_sys IS constant AC97_CLK_PERIOD : time := 83 ns; constant ETH_CLK_PERIOD : time := 7.7 ns; constant LOOP_BACK_EN : std_logic := '1'; + constant WITH_TLB : boolean := true; + constant KSEG_01_TRANSLATED : boolean := true; signal sys_rst_n_in : std_logic := '0'; signal sys_clk_in : std_logic := '1'; signal dip : unsigned(7 downto 0) := (others => '0'); @@ -146,7 +148,9 @@ uut: entity work.mips_sys GENERIC MAP ( sys_freq_in => 100.000, - cpu_freq => 100.000, + cpu_freq => 60.000, + WITH_TLB => WITH_TLB, + TRANSLATE_KSEG0_1 => KSEG_01_TRANSLATED, sdram_phaseshift => 0, tsvga => ts_vga_800_600_72 ) @@ -365,7 +369,7 @@ ac97_clk_gen : PROCESS FLASH_READ: process(sys_rst_n_in, sys_flash_ce, sys_flash_ssram_oe_n, sys_flash_ssram_a) type file_t is file of integer; - file load_flash : file_t open read_mode is "blittertest_tb.elf.flash.bin"; + file load_flash : file_t open read_mode is "test_dcache_sim.elf.flash.bin"; variable instr : integer; variable index : natural; variable temp : signed(31 downto 0);