From dfbec91a62de5f394c1df1af8c39d485b92a1dd4 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 26 Sep 2014 11:36:28 +0200 Subject: [PATCH] add modelsim simulation and start fixing init --- lib/sata/k7sataphy/__init__.py | 6 + lib/sata/k7sataphy/clocking.py | 24 +- lib/sata/k7sataphy/ctrl.py | 2 +- lib/sata/k7sataphy/gtx.py | 26 +- sim/compile_rtl.tcl | 11 + sim/compile_tb.tcl | 8 + sim/glbl.v | 66 +++++ sim/hdl_common/hdl_0in.tcl | 29 +++ sim/hdl_common/hdl_common.tcl | 406 +++++++++++++++++++++++++++++++ sim/hdl_common/hdl_formality.tcl | 32 +++ sim/hdl_common/hdl_modelsim.tcl | 80 ++++++ sim/hdl_common/hdl_ncsim.tcl | 91 +++++++ sim/hdl_common/hdl_quartus.tcl | 35 +++ sim/hdl_common/hdl_synopsys.tcl | 33 +++ sim/hdl_common/hdl_synplify.tcl | 36 +++ sim/hdl_common/hdl_xst.tcl | 37 +++ sim/sim.do | 32 +++ sim/top_tb.v | 43 ++++ 18 files changed, 978 insertions(+), 19 deletions(-) create mode 100644 sim/compile_rtl.tcl create mode 100644 sim/compile_tb.tcl create mode 100644 sim/glbl.v create mode 100644 sim/hdl_common/hdl_0in.tcl create mode 100644 sim/hdl_common/hdl_common.tcl create mode 100644 sim/hdl_common/hdl_formality.tcl create mode 100644 sim/hdl_common/hdl_modelsim.tcl create mode 100644 sim/hdl_common/hdl_ncsim.tcl create mode 100644 sim/hdl_common/hdl_quartus.tcl create mode 100644 sim/hdl_common/hdl_synopsys.tcl create mode 100644 sim/hdl_common/hdl_synplify.tcl create mode 100644 sim/hdl_common/hdl_xst.tcl create mode 100644 sim/sim.do create mode 100644 sim/top_tb.v diff --git a/lib/sata/k7sataphy/__init__.py b/lib/sata/k7sataphy/__init__.py index 77d112a5..676ba2c5 100644 --- a/lib/sata/k7sataphy/__init__.py +++ b/lib/sata/k7sataphy/__init__.py @@ -13,6 +13,12 @@ class K7SATAPHY(Module): self.source = Source([("d", 32)], True) gtx = K7SATAPHYGTX(pads, "SATA3") + self.comb += [ + #gtx.rxrate.eq(0b001), + #gtx.txrate.eq(0b001), + gtx.rxrate.eq(0b0), + gtx.txrate.eq(0b0), + ] clocking = K7SATAPHYClocking(pads, gtx) rxalign = K7SATAPHYRXAlign() rxconvert = K7SATAPHYRXConvert() diff --git a/lib/sata/k7sataphy/clocking.py b/lib/sata/k7sataphy/clocking.py index d257c7dc..bba81d15 100644 --- a/lib/sata/k7sataphy/clocking.py +++ b/lib/sata/k7sataphy/clocking.py @@ -34,10 +34,13 @@ class K7SATAPHYClocking(Module): # TX clocking refclk = Signal() self.specials += Instance("IBUFDS_GTE2", + i_CEB=0, i_I=pads.refclk_p, i_IB=pads.refclk_n, o_O=refclk ) + self.comb += gtx.gtrefclk0.eq(refclk) + mmcm_reset = Signal() mmcm_locked = Signal() mmcm_drp = DRPBus() @@ -52,10 +55,10 @@ class K7SATAPHYClocking(Module): # DRP i_DCLK=mmcm_drp.clk, i_DEN=mmcm_drp.en, o_DRDY=mmcm_drp.rdy, i_DWE=mmcm_drp.we, - i_DADDR=mmcm_drp.addr, i_DI=mmcm_drp.di, i_DO=mmcm_drp.do, + i_DADDR=mmcm_drp.addr, i_DI=mmcm_drp.di, o_DO=mmcm_drp.do, # VCO - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0, + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=6.666, p_CLKFBOUT_MULT_F=8.000, p_CLKFBOUT_PHASE=0.000, p_DIVCLK_DIVIDE=2, i_CLKIN1=mmcm_clk_i, i_CLKFBIN=mmcm_fb, o_CLKFBOUT=mmcm_fb, @@ -63,7 +66,7 @@ class K7SATAPHYClocking(Module): p_CLKOUT0_DIVIDE_F=4.000, p_CLKOUT0_PHASE=0.000, o_CLKOUT0=mmcm_clk0_o, # CLK1 - p_CLKOUT1_DIVIDE_F=8.000, p_CLKOUT1_PHASE=0.000, o_CLKOUT1=mmcm_clk1_o, + p_CLKOUT1_DIVIDE=8, p_CLKOUT1_PHASE=0.000, o_CLKOUT1=mmcm_clk1_o, ), Instance("BUFG", i_I=mmcm_clk0_o, o_O=self.cd_sata_tx.clk), Instance("BUFG", i_I=mmcm_clk1_o, o_O=self.cd_sata.clk), @@ -130,16 +133,25 @@ class K7SATAPHYClocking(Module): ) # Reset + # initial reset generation + rst_cnt = Signal(8) + rst_cnt_done = Signal() + self.sync += \ + If(~rst_cnt_done, + rst_cnt.eq(rst_cnt+1) + ) + self.comb += rst_cnt_done.eq(rst_cnt==255) + self.comb += [ # GTXE2 gtx.rxuserrdy.eq(gtx.cplllock), gtx.txuserrdy.eq(gtx.cplllock), # TX - gtx.gttxreset.eq(self.reset | self.transceiver_reset | ~gtx.cplllock), + gtx.gttxreset.eq(rst_cnt_done & (self.reset | self.transceiver_reset | ~gtx.cplllock)), # RX - gtx.gtrxreset.eq(self.reset | self.transceiver_reset | ~gtx.cplllock), + gtx.gtrxreset.eq(rst_cnt_done & (self.reset | self.transceiver_reset | ~gtx.cplllock)), # PLL - gtx.cpllreset.eq(self.reset) + gtx.cpllreset.eq(rst_cnt_done & self.reset) ] # SATA TX/RX clock domains self.specials += [ diff --git a/lib/sata/k7sataphy/ctrl.py b/lib/sata/k7sataphy/ctrl.py index 9e60007a..5f705397 100644 --- a/lib/sata/k7sataphy/ctrl.py +++ b/lib/sata/k7sataphy/ctrl.py @@ -157,7 +157,7 @@ class K7SATAPHYHostCtrl(Module): self.sync.sata += \ If(fsm.ongoing("SEND_ALIGN"), - If(self.rxdata[7:0] == K28_5, + If(self.rxdata[0:8] == K28_5, non_align_cnt.eq(non_align_cnt + 1) ).Else( non_align_cnt.eq(0) diff --git a/lib/sata/k7sataphy/gtx.py b/lib/sata/k7sataphy/gtx.py index ef26ecd9..21e98294 100644 --- a/lib/sata/k7sataphy/gtx.py +++ b/lib/sata/k7sataphy/gtx.py @@ -82,6 +82,8 @@ class K7SATAPHYGTX(Module): # Transmit Ports - TX Data Path interface self.gttxreset = Signal() + self.txpcsreset = Signal() + self.txpmareset = Signal() self.txdata = Signal() self.txoutclk = Signal() self.txoutclkfabric = Signal() @@ -93,7 +95,7 @@ class K7SATAPHYGTX(Module): self.txresetdone = Signal() # Transmit Ports - TX Ports for PCI Express - self.txelecidle = Signal() + self.txelecidle = Signal(reset=1) # Transmit Ports - TX Ports for SATA self.txcomfinish = Signal() @@ -128,7 +130,7 @@ class K7SATAPHYGTX(Module): "p_SIM_TX_EIDLE_DRIVE_LEVEL":"X", "p_SIM_RESET_SPEEDUP":"TRUE", "p_SIM_CPLLREFCLK_SEL":0b001, - "p_SIM_VERSION":"4.0", + "p_SIM_VERSION":"3.0", # RX Byte and Word Alignment Attributes "p_ALIGN_COMMA_DOUBLE":"FALSE", @@ -138,9 +140,9 @@ class K7SATAPHYGTX(Module): "p_ALIGN_MCOMMA_VALUE":K28_5, "p_ALIGN_PCOMMA_DET":"TRUE", "p_ALIGN_PCOMMA_VALUE":~K28_5, - "p_SHOW_REALIGN_COMMA":"FALSE", + "p_SHOW_REALIGN_COMMA":"TRUE", "p_RXSLIDE_AUTO_WAIT":7, - "p_RXSLIDE_MODE":"OFF", + "p_RXSLIDE_MODE":"PCS", "p_RX_SIG_VALID_DLY":10, # RX 8B/10B Decoder Attributes @@ -303,7 +305,7 @@ class K7SATAPHYGTX(Module): # TX Buffer Attributes "p_TXBUF_EN":"FALSE", - "p_TXBUF_RESET_ON_RATE_CHANGE":"FALSE", + "p_TXBUF_RESET_ON_RATE_CHANGE":"TRUE", "p_TXDLY_CFG":0x1f, "p_TXDLY_LCFG":0x030, "p_TXDLY_TAP_CFG":0, @@ -429,7 +431,7 @@ class K7SATAPHYGTX(Module): i_DRPADDR=self.drp.addr, i_DRPCLK=self.drp.clk, i_DRPDI=self.drp.di, - i_DRPDO=self.drp.do, + o_DRPDO=self.drp.do, i_DRPEN=self.drp.en, o_DRPRDY=self.drp.rdy, i_DRPWE=self.drp.we, @@ -490,7 +492,7 @@ class K7SATAPHYGTX(Module): i_RXUSRCLK2=self.rxusrclk2, # Receive Ports - FPGA RX interface Ports - i_RXDATA=self.rxdata, + o_RXDATA=self.rxdata, # Receive Ports - Pattern Checker Ports #o_RXPRBSERR=, @@ -505,7 +507,7 @@ class K7SATAPHYGTX(Module): i_RXDFEXYDOVRDEN=0, # Receive Ports - RX 8B/10B Decoder Ports - i_RXDISPERR=self.rxdisperr, + o_RXDISPERR=self.rxdisperr, o_RXNOTINTABLE=self.rxnotintable, # Receive Ports - RX AFE @@ -730,8 +732,8 @@ class K7SATAPHYGTX(Module): i_TXSTARTSEQ=0, # Transmit Ports - TX Initialization and Reset Ports - i_TXPCSRESET=0, - i_TXPMARESET=0, + i_TXPCSRESET=self.txpcsreset, + i_TXPMARESET=self.txpmareset, o_TXRESETDONE=self.txresetdone, # Transmit Ports - TX OOB signalling Ports @@ -820,8 +822,8 @@ class K7SATAPHYRXConvert(Module): # rearrange data self.comb += [ self.source.stb.eq(self.rx_fifo.source.stb), - self.source.payload.data.eq(Cat(rx_fifo.source.raw[0:32], rx_fifo.source.raw[36:36+32])), - self.source.payload.charisk.eq(Cat(rx_fifo.source.raw[32:36], rx_fifo.source.raw[36+32:36+36])), + self.source.payload.data.eq(Cat(rx_fifo.source.raw[0:16], rx_fifo.source.raw[18:18+16])), + self.source.payload.charisk.eq(Cat(rx_fifo.source.raw[16:18], rx_fifo.source.raw[18+16:18+18])), self.rx_fifo.source.ack.eq(self.source.ack), ] diff --git a/sim/compile_rtl.tcl b/sim/compile_rtl.tcl new file mode 100644 index 00000000..1daeb27a --- /dev/null +++ b/sim/compile_rtl.tcl @@ -0,0 +1,11 @@ +############################################################################## +# +# Compilation of SoC RTL files +# +############################################################################## + +set HDL_WORK "work" + +hdl_compile -v 2005 { + ../../misoc/build/testdesign-kc705_impact.v +} \ No newline at end of file diff --git a/sim/compile_tb.tcl b/sim/compile_tb.tcl new file mode 100644 index 00000000..4c880f10 --- /dev/null +++ b/sim/compile_tb.tcl @@ -0,0 +1,8 @@ +############################################################################## +# +# Compilation of MiSoC TB files +# +############################################################################## +hdl_compile -sim glbl.v + +hdl_compile -sim top_tb.v diff --git a/sim/glbl.v b/sim/glbl.v new file mode 100644 index 00000000..0e0b3c6c --- /dev/null +++ b/sim/glbl.v @@ -0,0 +1,66 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.15 2011/08/25 22:54:30 fphillip Exp $ + +`timescale 1 ps / 1 ps + +module glbl (); + + parameter ROC_WIDTH = 100000; + parameter TOC_WIDTH = 0; + +//-------- STARTUP Globals -------------- + wire GSR; + wire GTS; + wire GWE; + wire PRLD; + tri1 p_up_tmp; + tri (weak1, strong0) PLL_LOCKG = p_up_tmp; + + wire PROGB_GLBL; + wire CCLKO_GLBL; + + reg GSR_int; + reg GTS_int; + reg PRLD_int; + +//-------- JTAG Globals -------------- + wire JTAG_TDO_GLBL; + wire JTAG_TCK_GLBL; + wire JTAG_TDI_GLBL; + wire JTAG_TMS_GLBL; + wire JTAG_TRST_GLBL; + + reg JTAG_CAPTURE_GLBL; + reg JTAG_RESET_GLBL; + reg JTAG_SHIFT_GLBL; + reg JTAG_UPDATE_GLBL; + reg JTAG_RUNTEST_GLBL; + + reg JTAG_SEL1_GLBL = 0; + reg JTAG_SEL2_GLBL = 0 ; + reg JTAG_SEL3_GLBL = 0; + reg JTAG_SEL4_GLBL = 0; + + reg JTAG_USER_TDO1_GLBL = 1'bz; + reg JTAG_USER_TDO2_GLBL = 1'bz; + reg JTAG_USER_TDO3_GLBL = 1'bz; + reg JTAG_USER_TDO4_GLBL = 1'bz; + + assign (weak1, weak0) GSR = GSR_int; + assign (weak1, weak0) GTS = GTS_int; + assign (weak1, weak0) PRLD = PRLD_int; + + initial begin + GSR_int = 1'b1; + PRLD_int = 1'b1; + #(ROC_WIDTH) + GSR_int = 1'b0; + PRLD_int = 1'b0; + end + + initial begin + GTS_int = 1'b1; + #(TOC_WIDTH) + GTS_int = 1'b0; + end + +endmodule diff --git a/sim/hdl_common/hdl_0in.tcl b/sim/hdl_common/hdl_0in.tcl new file mode 100644 index 00000000..0f8cf423 --- /dev/null +++ b/sim/hdl_common/hdl_0in.tcl @@ -0,0 +1,29 @@ +set HDL_TOOLTYPE SIMULATION +set HDL_TOOLNAME 0in +set HDL_PUTS puts +set HDL_MSG_FORMAT "********** %s **********" + +proc hdl_tool_library {lib} { +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + set command analyze + lappend command -work [string tolower $library] + switch $format { + "vhdl" { + lappend command -vhdl + } + "verilog" { + foreach d $define { + lappend command +define+$d + } + foreach i $incdirs { + lappend command +incdir+$i + } + } + } + foreach f $files { + lappend command $f + } + puts [eval $command] +} diff --git a/sim/hdl_common/hdl_common.tcl b/sim/hdl_common/hdl_common.tcl new file mode 100644 index 00000000..abb7b585 --- /dev/null +++ b/sim/hdl_common/hdl_common.tcl @@ -0,0 +1,406 @@ +############################################################################## +# Define some global variables +############################################################################## + +if {![info exists HDL_LIBRARIES]} { + set HDL_LIBRARIES () +} +set HDL_TARGET "default_target" +set HDL_PATH [pwd] +set HDL_WORK "work" + +# Uncomment the following line to generate a log file for debug +#set HDL_LOG [open "hdl_common.log" "w"] + +############################################################################## +# Some utilities +############################################################################## + +# Extract first element from a list (for argument processing) +proc extract_first {list_name {option ""}} { + upvar $list_name mylist + if {[string length $option]>0 && [llength $mylist]==0} { + error "Missing argument for option $option" + } + set first [lindex $mylist 0] + if {[string length $option]>0 && [string match "-*" $first]} { + error "Missing argument for option $option" + } + set mylist [lrange $mylist 1 end] + return $first +} + +# Clean-up file path +proc clean_path {f} { + # Add trailing / + set f "$f/" + # Remove double / (excepted leading) + while {[regsub {(.)//} $f "\1/" f]} {} + # Remove . + while {[regsub {/\./} $f "/" f]} {} + # Remove .. + while {[regsub {/[^/.]+/\.\./} $f "/" f]} {} + # Remove trailing / + regsub {/$} $f "" f + return $f +} + +# Translate relative paths to absolute paths +proc get_full_path {files} { + global HDL_PATH + set r {} + # For DOS paths, replace \ by / + regsub -all {\\} $files "/" files + foreach f $files { + hdl_debug " $f" + # Append file path + if {[string match "/*" $f] || [string match "?:/*" $f]} { + # Path is an absolute path + hdl_warning "Using absolute path $f" + } else { + # Path is a relative path + set f [clean_path $HDL_PATH/$f] + } + hdl_debug " => $f" + lappend r $f + # Check access to file + if {![file readable $f]} { + error "Cannot read file $f" + } + } + return $r +} + +# Check if value match any pattern in the list +proc match_list {mlist value} { + set match 0 + foreach m $mlist { + if [string match $m $value] { + set match 1 + } + } + return $match +} + +proc get_lib_path {} { + if [file isdirectory "/cad/trash"] { + set libs "/cad/trash[pwd]/libs" + } elseif [file isdirectory "e:/trash"] { + set libs [pwd] + # Replace D:/ by D/ for local drive + regsub ":" $libs "" libs + # Remove leading // for network drive + regsub "//" $libs "" libs + set libs "e:/trash/$libs" + } else { + # No "trash" directory on this machine => work locally + set libs "./libs" + } + file mkdir $libs + return $libs +} + +############################################################################## +# Procedures to display messages +############################################################################## + +# Write message to log file if logging enabled +proc hdl_log { msg } { + global HDL_LOG + if [info exists HDL_LOG] { + puts $HDL_LOG $msg + flush $HDL_LOG + } + return +} + +# Debug messages are sent only to log file +proc hdl_debug { msg } { + hdl_log "hdl_common - Debug: $msg" + return +} + +# According to the tool, "puts" or "echo" should be used +# HDL_PUTS variable is used for this purpose +# All message are also sent to log file +proc hdl_puts { msg } { + global HDL_PUTS + $HDL_PUTS $msg + hdl_log $msg + return +} + +proc hdl_note { msg } { + hdl_puts "hdl_common - Note: $msg" + return +} + +proc hdl_warning { msg } { + hdl_puts "hdl_common - Warning: $msg" + return +} + +proc hdl_message { args } { + global HDL_MSG_FORMAT + hdl_puts [format $HDL_MSG_FORMAT [join $args " "]] + return +} + +############################################################################## +# Procedures for compilation scripts +############################################################################## + +# Compile source files +proc hdl_compile { args } { + global HDL_TOOLTYPE HDL_TOOLNAME HDL_TARGET HDL_LIBRARIES HDL_WORK + # Default values + set format "" + set version "93" + set files {} + set incdirs {} + set only_for {} + set not_for {} + set toolname {} + set tooltype "*" + set library $HDL_WORK + set define {} + set behavioral 0 + + # Decode arguments + while {[llength $args]} { + set arg [extract_first args] + switch -glob -- $arg { + "-f" { + set format [extract_first args "-f"] + } + "-v" { + set version [extract_first args "-version"] + } + "-only_for" { + set only_for [concat $only_for [extract_first args "-only_for"]] + } + "-not_for" { + set not_for [concat $not_for [extract_first args "-not_for"]] + } + "-sim" { + set tooltype "SIMULATION" + set behavioral 1 + } + "-syn" { + set tooltype "SYNTHESIS" + set behavioral 0 + } + "-tool" { + set toolname [concat $toolname [extract_first args "-tool"]] + } + "-incdir" { + set incdirs [concat $incdirs [extract_first args "-incdir"]] + } + "-lib" { + set library [extract_first args "-lib"] + if {[string match "work" $library]} { + hdl_warning "Specifying '-lib work' is useless" + } + } + "-define" { + set define [concat $define [extract_first args "-define"]] + } + "-*" { + error "Unsupported argument $arg" + } + default { + set files [concat $files $arg] + } + } + } + + # Check arguments + if {![llength $files]} { + error "No file to compile" + } + # If no "-only_for" option given, use file for any target + if {[llength $only_for]==0} { + set only_for {*} + } + # If no "-tool" option given, use file for any tool + if {[llength $toolname]==0} { + set toolname {*} + } + + # Check if compilation is required + if {[match_list $only_for $HDL_TARGET] && ![match_list $not_for $HDL_TARGET] && + [string match $tooltype $HDL_TOOLTYPE] && [match_list $toolname $HDL_TOOLNAME]} { + # Create library if needed + if {[lsearch -exact $HDL_LIBRARIES $library]<0} { + hdl_note "Creating library $library" + lappend HDL_LIBRARIES $library + hdl_tool_library $library + } + # Compile files + foreach f $files { + # Warning if dummy file is used + if {[string match "*dummy*" [string tolower $f]]} { + hdl_note "Using [file tail $f]" + } + # Determine format + if {![llength $format]} { + if {[string match "*.vh?*" $f]} { + set format "vhdl" + } elseif {[string match "*.v*" $f]} { + set format "verilog" + set version "sv" + } elseif {[string match "*.sv" $f]} { + set format "verilog" + set version "sv" + } + } + } + hdl_tool_compile $format $version [get_full_path $incdirs] $library $define [get_full_path $files] $behavioral + } + return +} + +# Change directory +proc hdl_cd { path } { + global HDL_PATH + set HDL_PATH [get_full_path $path] + hdl_debug "New path is $HDL_PATH" + return +} + +# Execute script +proc hdl_source { args } { + global HDL_PATH HDL_TARGET HDL_WORK HDL_TOOLTYPE HDL_TOOLNAME + # Save original values + set save_path $HDL_PATH + set save_target $HDL_TARGET + set save_work $HDL_WORK + # Default value + set files {} + set toolname {} + set tooltype "*" + set only_for {} + set not_for {} + # Process options + while {[llength $args]} { + set arg [extract_first args] + switch -glob -- $arg { + "-lib" { + set HDL_WORK [extract_first args "-lib"] + if {[string match "work" $HDL_WORK]} { + hdl_warning "Specifying '-lib work' is useless" + } + } + "-target" { + set HDL_TARGET [extract_first args "-target"] + } + "-sim" { + set tooltype "SIMULATION" + set behavioral 1 + } + "-syn" { + set tooltype "SYNTHESIS" + set behavioral 0 + } + "-tool" { + set toolname [concat $toolname [extract_first args "-tool"]] + } + "-only_for" { + set only_for [concat $only_for [extract_first args "-only_for"]] + } + "-not_for" { + set not_for [concat $not_for [extract_first args "-not_for"]] + } + "-*" { + error "Unsupported argument $arg" + } + default { + set files [concat $files $arg] + } + } + } + # Check arguments + if {![llength $files]} { + error "No script specified" + } + # If no "-only_for" option given, use file for any target + if {[llength $only_for]==0} { + set only_for {*} + } + # If no "-tool" option given, use file for any tool + if {[llength $toolname]==0} { + set toolname {*} + } + + # Check if compilation is required + if {[match_list $only_for $HDL_TARGET] && ![match_list $not_for $HDL_TARGET] && + [string match $tooltype $HDL_TOOLTYPE] && [match_list $toolname $HDL_TOOLNAME]} { + # Source scripts + foreach script $files { + # Change directory to script location + hdl_cd [file dirname $script] + # Execute script + set script [get_full_path [file tail $script]] + hdl_note "Source $script ($HDL_TARGET)" + uplevel source $script + # Restore original path + set HDL_PATH $save_path + hdl_debug "Back to directory $HDL_PATH" + } + } + # Restore original values + set HDL_TARGET $save_target + set HDL_WORK $save_work + #puts "Back to $HDL_PATH" + return +} + +# Specify target +proc hdl_set_target { args } { + global HDL_TARGET env + # Default values + set use_env 0 + set default "" + set target "" + # Decode arguments + while {[llength $args]} { + set arg [extract_first args] + switch -glob -- $arg { + "-env" { + set use_env 1 + } + "-default" { + set default [extract_first args "-default"] + } + "-*" { + error "Unsupported argument $arg" + } + default { + set target $arg + } + } + } + # Check arguments + if {[llength $target]} { + set HDL_TARGET $target + hdl_note "Using target $HDL_TARGET" + } elseif {$use_env} { + if {[info exists env(HDL_TARGET)]} { + set HDL_TARGET $env(HDL_TARGET) + hdl_note "Using target $HDL_TARGET (from environment variable HDL_TARGET)" + } elseif {[llength $default]} { + set HDL_TARGET $default + hdl_note "Using default target $HDL_TARGET (environment variable HDL_TARGET not defined)" + } else { + error "No environment variable defined and no default target" + } + } else { + error "Missing argument" + } + return +} + +############################################################################## + +# clock is an invalid command name for Synplify at least until version 2010.09 +# hdl_debug [clock format [clock seconds]] diff --git a/sim/hdl_common/hdl_formality.tcl b/sim/hdl_common/hdl_formality.tcl new file mode 100644 index 00000000..b33c8179 --- /dev/null +++ b/sim/hdl_common/hdl_formality.tcl @@ -0,0 +1,32 @@ +set HDL_TOOLTYPE SYNTHESIS +set HDL_TOOLNAME formality +set HDL_PUTS puts +set HDL_MSG_FORMAT "\n********** %s **********\n" + +proc hdl_tool_library {lib} { + define_design_lib $lib -path lib_$lib +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + global search_path + if {[llength $define]} { + error "-define not yet supported" + } + # Add include paths + set search_path [concat $incdirs $search_path] + # Compile files + foreach f $files { + if {[string match $format "vhdl"]} { + if {[string match $version "93"]} { + read_vhdl -93 -libname $library $f + } else { + read_vhdl -libname $library $f + } + } else { + read_verilog -01 -libname $library $f + } + puts "" + } + # Remove include paths + set search_path [lrange $search_path [llength $incdirs] end] +} diff --git a/sim/hdl_common/hdl_modelsim.tcl b/sim/hdl_common/hdl_modelsim.tcl new file mode 100644 index 00000000..a9c43a9a --- /dev/null +++ b/sim/hdl_common/hdl_modelsim.tcl @@ -0,0 +1,80 @@ +# Set the option CHECK_SYNTHESIS to 1 if you want to have -check_synthesis in simulation. For now +# tools like Modelsim generate too many false positives so it is disabled by default: + +set CHECK_SYNTHESIS 0 + +set NO_DEBUG 0 + +set HDL_TOOLTYPE SIMULATION +set HDL_TOOLNAME modelsim +set HDL_PUTS echo +set HDL_MSG_FORMAT "********** %s **********" + +# Return the directory containing library lib +proc getvmap {lib} { + if {[catch {vmap $lib} result]} { + # Library does not exist yet => default directory + return $lib + } + set dir "" + # Get directory returned by vmap + regexp { maps to directory (.*)\.$} $result match dir + return $dir +} + +proc hdl_tool_library {lib} { + set lib [string tolower $lib] + # Delete library + set path [getvmap $lib] + if {[file isdirectory $path]} { + catch { + vdel -lib $path -all + } + } + # Create library + set path [get_lib_path]/$lib + vlib $path + vmap $lib $path +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + global CHECK_SYNTHESIS + global NO_DEBUG + switch $format { + "vhdl" { + set command vcom + if { $version == 87 } { + lappend command -87 + } elseif { $version == 93 } { + lappend command -93 + } + # More strict for synthesizable modules + if { ! $behavioral && $CHECK_SYNTHESIS } { + lappend command -check_synthesis + } + } + "verilog" { + set command vlog + if {$version == "sv"} { + lappend command -sv + } + lappend command -timescale "1ns/1ns" + foreach d $define { + lappend command +define+$d + } + foreach i $incdirs { + lappend command +incdir+$i + } + } + } + if {$NO_DEBUG} { + lappend command -nodebug + } + lappend command -work [string tolower $library] + lappend command -quiet + foreach f $files { + lappend command $f + } + puts -nonewline [eval $command] + return +} diff --git a/sim/hdl_common/hdl_ncsim.tcl b/sim/hdl_common/hdl_ncsim.tcl new file mode 100644 index 00000000..d983f231 --- /dev/null +++ b/sim/hdl_common/hdl_ncsim.tcl @@ -0,0 +1,91 @@ +set HDL_TOOLTYPE SIMULATION +set HDL_TOOLNAME ncsim +set HDL_PUTS puts +set HDL_MSG_FORMAT "********** %s **********" + +if {![file exists hdl.var]} { + hdl_note "Creating default hdl.var" + exec echo "DEFINE WORK work" > hdl.var +} + +if {![file exists cds.lib]} { + hdl_note "Creating default cds.lib" + exec echo "# This file was created automatically by hdl_ncsim.tcl" > cds.lib + exec echo "# You can edit this file" >> cds.lib + exec echo "# Please add the libraries that are not handled by hdl_ncsim.tcl" >> cds.lib + exec echo "# (for example the Xilinx libraries compiled with compxlib)" >> cds.lib + exec echo {INCLUDE ${CDS_INST_DIR}/tools/inca/files/cds.lib} >> cds.lib +} + +proc no_matching_line {pattern file} { + return [catch {exec grep -q $pattern $file}] +} + +if {[no_matching_line "^INCLUDE mycds.lib$" cds.lib]} { + hdl_note "Including mycds.lib in cds.lib" + exec echo "INCLUDE mycds.lib" >> cds.lib +} + +hdl_note "Clean-up mycds.lib" +exec echo "# This file is written automatically by hdl_ncsim.tcl" > mycds.lib +exec echo "# Do not edit this file" >> mycds.lib +exec echo "# It will be overwritten at each compilation" >> mycds.lib + +proc hdl_tool_library {lib} { + set lib [string tolower $lib] + set path [get_lib_path]/${lib}_nc + exec echo "DEFINE $lib $path" >> mycds.lib + exec touch $path + exec rm -r $path + exec mkdir $path +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + switch $format { + "vhdl" { + set command "ncvhdl" + if {$version != 87} { + lappend command -v93 + } + # Less strict VHDL for behavioral modules + if {$behavioral} { + lappend command -relax + } + } + "verilog" { + set command "ncvlog" + if {$version == "sv"} { + lappend command -sv + } + foreach d $define { + lappend command -define $d + } + foreach i $incdirs { + lappend command -incdir $i + } + } + } + lappend command -work [string tolower $library] + lappend command -nocopyright + foreach f $files { + lappend command $f + } + eval $command +} + +# Allow launching NC-Sim tools directly in TCL +proc ncvlog { args } { + puts -nonewline [eval exec -keepnewline ncvlog $args] +} +proc ncvhdl { args } { + puts -nonewline [eval exec -keepnewline ncvhdl $args] +} +proc ncelab { args } { + puts -nonewline [eval exec -keepnewline ncelab $args] +} +proc ncsdfc { args } { + puts -nonewline [eval exec -keepnewline ncsdfc $args] +} +proc ncsim { args } { + puts -nonewline [eval exec -keepnewline ncsim $args] +} diff --git a/sim/hdl_common/hdl_quartus.tcl b/sim/hdl_common/hdl_quartus.tcl new file mode 100644 index 00000000..69ba6144 --- /dev/null +++ b/sim/hdl_common/hdl_quartus.tcl @@ -0,0 +1,35 @@ +set HDL_TOOLTYPE SYNTHESIS +set HDL_TOOLNAME QuartusII +set HDL_PUTS puts +set HDL_MSG_FORMAT "********** %s **********" + + +proc hdl_tool_library {lib_list} { +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + #if {[llength $incdirs]} { + # error "-incdir not yet supported" + #} + switch $format { + "vhdl" { + foreach f $files { + set_global_assignment -name VHDL_FILE $f -library $library + } + } + "verilog" { + foreach d $define { + set_global_assignment -name VERILOG_MACRO $d + } + foreach f $files { + set_global_assignment -name VERILOG_FILE $f -library $library + } + } + } +} + +if { [catch { puts "Quartus hdl_common script" } ] } { + # Disable puts for Quartus (doesn't work with the GUI since no stdout channel) + proc hdl_puts { msg } { + } +} diff --git a/sim/hdl_common/hdl_synopsys.tcl b/sim/hdl_common/hdl_synopsys.tcl new file mode 100644 index 00000000..24d53d97 --- /dev/null +++ b/sim/hdl_common/hdl_synopsys.tcl @@ -0,0 +1,33 @@ +set HDL_TOOLTYPE SYNTHESIS +set HDL_TOOLNAME synopsys +set HDL_PUTS puts +set HDL_MSG_FORMAT "\n********** %s **********\n" + +proc hdl_tool_library {lib_list} { + foreach l $lib_list { + set path [get_lib_path]/$l + sh touch $path + sh rm -r $path + sh mkdir $path + define_design_lib $l -path $path + } +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + global search_path + if {[llength $define]} { + error "-define not yet supported" + } + # Add include paths + set search_path [concat $incdirs $search_path] + # Compile files + foreach f $files { + if {[string match $format "vhdl"]} { + puts "Compiling source file $f" + } + analyze -format $format -work $library $f + puts "" + } + # Remove include paths + set search_path [lrange $search_path [llength $incdirs] end] +} diff --git a/sim/hdl_common/hdl_synplify.tcl b/sim/hdl_common/hdl_synplify.tcl new file mode 100644 index 00000000..46f915a4 --- /dev/null +++ b/sim/hdl_common/hdl_synplify.tcl @@ -0,0 +1,36 @@ +set HDL_TOOLTYPE SYNTHESIS +set HDL_TOOLNAME synplify +set HDL_PUTS puts +set HDL_MSG_FORMAT "********** %s **********" + +proc hdl_tool_library {lib_list} { +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + if {[llength $define]} { + error "-define not yet supported" + } + switch $format { + "vhdl" { + foreach f $files { + add_file -vhdl -lib $library $f + } + } + "verilog" { + foreach i $incdirs { + set_option -include_path "$i" + } + foreach f $files { + add_file -verilog $f + } + } + "ngc" { + foreach i $incdirs { + set_option -include_path "$i" + } + foreach f $files { + add_file -xilinx $f + } + } + } +} diff --git a/sim/hdl_common/hdl_xst.tcl b/sim/hdl_common/hdl_xst.tcl new file mode 100644 index 00000000..53f489fa --- /dev/null +++ b/sim/hdl_common/hdl_xst.tcl @@ -0,0 +1,37 @@ +set HDL_TOOLTYPE SYNTHESIS +set HDL_TOOLNAME XST +set HDL_PUTS puts +set HDL_MSG_FORMAT "********** %s **********" + +proc hdl_tool_library {lib_list} { +} + +proc hdl_tool_compile {format version incdirs library define files behavioral} { + global PROJECT_FILE + + # do not use append, based on http://wiki.tcl.tk/1241 + set projectfile [open $PROJECT_FILE {WRONLY CREAT APPEND}] + + if {[llength $define]} { + error "-define not yet supported" + } + if {[llength $incdirs]} { + error "-incdirs not yet supported" + } + puts "checking format" + switch $format { + "vhdl" { + foreach f $files { + puts $projectfile "vhdl $library $f" + } + } + "verilog" { + foreach f $files { + puts $projectfile "verilog $library $f" + } + } + } + + close $projectfile + +} \ No newline at end of file diff --git a/sim/sim.do b/sim/sim.do new file mode 100644 index 00000000..0015f47c --- /dev/null +++ b/sim/sim.do @@ -0,0 +1,32 @@ +transcript on +transcript file CustomTranscript + +############################################################################## +# Setup libraries +vlib work +vmap unisims_ver D:/Installs/Logiciels/Xilinx/ISE14.6/14.6/ISE_DS/ISE/verilog/mti_se/10.1c/nt/unisims_ver +vmap secureip D:/Installs/Logiciels/Xilinx/ISE14.6/14.6/ISE_DS/ISE/verilog/mti_se/10.1c/nt/secureip + +# Compile design +############################################################################## + +source hdl_common/hdl_common.tcl +source hdl_common/hdl_modelsim.tcl + +hdl_source compile_rtl.tcl +hdl_source compile_tb.tcl + +############################################################################## +# Run simulation +############################################################################## + +vsim -t ps -L secureip -L unisims_ver -novopt glbl top_tb + +set NumericStdNoWarnings 1 +set StdArithNoWarnings 1 + +log -r * +do wave.do + +onbreak {resume} +run 2000us diff --git a/sim/top_tb.v b/sim/top_tb.v new file mode 100644 index 00000000..fa9700af --- /dev/null +++ b/sim/top_tb.v @@ -0,0 +1,43 @@ +`timescale 1ns/1ps + +module top_tb(); + +reg refclk_p; +wire refclk_n; +initial refclk_p = 1'b1; +always #3.33 refclk_p = ~refclk_p; +assign refclk_n = ~refclk_p; + +reg clk200_p; +wire clk200_n; +initial clk200_p = 1'b1; +always #2.5 clk200_p = ~clk200_p; +assign clk200_n = ~clk200_p; + +wire sata_txp; +wire sata_txn; +wire sata_rxp; +wire sata_rxn; + +top dut( + .serial_cts(1'b0), + .serial_rts(1'b0), + .serial_tx(), + .serial_rx(1'b0), + .clk200_p(clk200_p), + .clk200_n(clk200_n), + .sata_host_refclk_p(refclk_p), + .sata_host_refclk_n(refclk_n), + .sata_host_txp(sata_txp), + .sata_host_txn(sata_txn), + .sata_host_rxp(sata_rxp), + .sata_host_rxn(sata_rxn), + .sata_device_refclk_p(refclk_p), + .sata_device_refclk_n(refclk_n), + .sata_device_txp(sata_rxp), + .sata_device_txn(sata_rxn), + .sata_device_rxp(sata_txp), + .sata_device_rxn(sata_txn) +); + +endmodule -- 2.30.2