Skip to content

Commit

Permalink
ADD: improve IP generation flow
Browse files Browse the repository at this point in the history
  • Loading branch information
T-K-233 committed Dec 22, 2024
1 parent 6a07d07 commit 63bc04b
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 69 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ toolchains/mill
# Vivado
vivado*.jou
vivado*.log
vivado*.str
.gen/
.srcs/
.ip_user_files/

98 changes: 33 additions & 65 deletions src/main/scala/Elaborate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,22 @@ object ParseModuleName {
}
}

object CreateVivadoDirectory {
def apply(vivado_project_dir: String): Unit = {
new File(vivado_project_dir).mkdirs()
new File(s"${vivado_project_dir}/scripts").mkdirs()
}
}



object GenerateVerilog extends App {
val (module_name, remaining_args) = ParseModuleName(args)

val vivado_project_dir = "out/VivadoProject"
CreateVivadoDirectory(vivado_project_dir)


val moduleClass = () => {
val module = Class.forName(module_name)
.getDeclaredConstructor()
Expand Down Expand Up @@ -54,6 +67,8 @@ object GenerateBitstream extends App {
val project_source_dir = "src/main"
val vivado_project_dir = "out/VivadoProject"

CreateVivadoDirectory(vivado_project_dir)

/* Arty A7 100T */
// val fpga_part = "xc7a100ticsg324-1L"
// val board_part = "digilentinc.com:arty-a7-100t:part0:1.1"
Expand Down Expand Up @@ -83,16 +98,12 @@ object GenerateBitstream extends App {
)


val chipyard_sources = new File("chipyard/sims/verilator/generated-src/chipyard.harness.TestHarness.WithAXI4LiteTinyRocketConfig/gen-collateral").listFiles(new FileFilter {
val chipyard_sources = new File("chipyard/sims/verilator/generated-src/chipyard.harness.TestHarness.TinyRocketConfig/gen-collateral").listFiles(new FileFilter {
def accept(file: File): Boolean = file.isFile || file.isDirectory
}).flatMap(file => if (file.isDirectory) file.listFiles().map(_.getAbsolutePath) else Array(file.getAbsolutePath))
// Exclude files listed in excluded_sources
.filterNot(source => excluded_sources.contains(new File(source).getName))

// create directory
new File(vivado_project_dir).mkdirs()
new File(s"${vivado_project_dir}/scripts").mkdirs()

{
// create a run.tcl file
val run_tcl = new PrintWriter(s"${vivado_project_dir}/scripts/create_project.tcl")
Expand All @@ -111,83 +122,40 @@ object GenerateBitstream extends App {


// add sources
run_tcl.print(s"add_files")
sources.foreach(source => {
run_tcl.println(s"add_files ${source}")
run_tcl.println(s" ${source} \\")
})
run_tcl.println("")

run_tcl.print(s"add_files")
verilog_sources.foreach(source => {
run_tcl.println(s"add_files ${source}")
run_tcl.println(s" ${source} \\")
})
run_tcl.println("")

run_tcl.print(s"add_files")
chipyard_sources.foreach(source => {
run_tcl.println(s"add_files ${source}")
run_tcl.println(s" ${source} \\")
})
run_tcl.println("")

run_tcl.println(s"set_property top ${module_name} [current_fileset]")


// create Vivado IPs
/* create Vivado IPs */
run_tcl.println("update_ip_catalog")

{
val ip_name = "clk_wiz_0"

run_tcl.println(s"create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name ${ip_name}")
// run_tcl.println("""
// set_property -dict [list \
// CONFIG.CLKOUT1_JITTER {193.154} \
// CONFIG.CLKOUT1_PHASE_ERROR {109.126} \
// CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {25} \
// CONFIG.MMCM_CLKFBOUT_MULT_F {8.500} \
// CONFIG.MMCM_CLKOUT0_DIVIDE_F {42.500} \
// ] [get_ips clk_wiz_0]""")
run_tcl.println(s"""
set_property -dict [list \\
CONFIG.CLKOUT1_JITTER {125.247} \\
CONFIG.CLKOUT1_PHASE_ERROR {98.575} \\
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50} \\
CONFIG.CLKOUT2_JITTER {175.402} \\
CONFIG.CLKOUT2_PHASE_ERROR {98.575} \\
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {25} \\
CONFIG.CLKOUT2_USED {true} \\
CONFIG.MMCM_CLKFBOUT_MULT_F {10.000} \\
CONFIG.MMCM_CLKOUT0_DIVIDE_F {8.000} \\
CONFIG.MMCM_CLKOUT1_DIVIDE {40} \\
CONFIG.NUM_OUT_CLKS {2} \\
] [get_ips ${ip_name}]""")


run_tcl.println(s"generate_target {instantiation_template} [get_ips ${ip_name}]")
run_tcl.println("update_compile_order -fileset sources_1")
run_tcl.println(s"generate_target all [get_ips ${ip_name}]")
run_tcl.println(s"catch { config_ip_cache -export [get_ips -all ${ip_name}] }")
run_tcl.println(s"export_ip_user_files -of_objects [get_ips ${ip_name}] -no_script -sync -force -quiet")
run_tcl.println(s"create_ip_run [get_ips ${ip_name}]")
}

{
val ip_name = "axis_data_fifo_0"
val create_ip_files = new File(s"${vivado_project_dir}/scripts").listFiles(new FileFilter {
def accept(file: File): Boolean = file.isFile && file.getName.contains("create_ip")
}).map(_.getAbsolutePath)

run_tcl.println(s"create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name ${ip_name}")
create_ip_files.foreach(file => {
run_tcl.println(s"source ${file}")
})

run_tcl.println(s"""
set_property -dict [list \\
CONFIG.HAS_TLAST {1} \\
CONFIG.TUSER_WIDTH {1} \\
] [get_ips ${ip_name}]
""")

run_tcl.println(s"generate_target {instantiation_template} [get_ips ${ip_name}]")
run_tcl.println("update_compile_order -fileset sources_1")
run_tcl.println(s"generate_target all [get_ips ${ip_name}]")
run_tcl.println(s"catch { config_ip_cache -export [get_ips -all ${ip_name}] }")
run_tcl.println(s"export_ip_user_files -of_objects [get_ips ${ip_name}] -no_script -sync -force -quiet")
run_tcl.println(s"create_ip_run [get_ips ${ip_name}]")

}

run_tcl.close()
run_tcl.flush() // make sure the file is written to the disk
run_tcl.flush()
}

{
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/TinyRocketArty100T.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TinyRocketArty100T extends Arty100TShell {
val clock_25 = Wire(Clock())


val clk_wiz = Module(new clk_wiz_0())
val clk_wiz = Module(new ClockingWizard(50, 25))
// clocking wizard connection
clk_wiz.io.clk_in1 := io.CLK100MHZ
clk_wiz.io.reset := ~io.ck_rst
Expand Down Expand Up @@ -118,7 +118,7 @@ class TinyRocketArty100T extends Arty100TShell {
io.eth_txd := udp_core.io.phy_txd


val udp_payload_axis_fifo = Module(new axis_data_fifo_0(8))
val udp_payload_axis_fifo = Module(new AXIStreamDataFifo(8))
udp_payload_axis_fifo.io.s_axis_aresetn := ~reset
udp_payload_axis_fifo.io.s_axis_aclk := clock

Expand Down
29 changes: 29 additions & 0 deletions src/main/scala/wrapper/AXIGPIOWrapper.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import chisel3.{BlackBox, _}
import chisel3.util._

import java.io.PrintWriter


class axi_gpio_0 extends BlackBox {
val io = IO(new Bundle {
Expand All @@ -9,4 +11,31 @@ class axi_gpio_0 extends BlackBox {
val gpio_io_o = Output(UInt(32.W))
val gpio_io_t = Output(UInt(32.W))
})

def generate_tcl_script(): Unit = {
val vivado_project_dir = "out/VivadoProject"
val ip_name = "AXIStreamDataFifo"
val ip_name_lower = ip_name.toLowerCase()

val tcl_script = new PrintWriter(s"${vivado_project_dir}/scripts/create_ip_${ip_name_lower}.tcl")

tcl_script.println(s"create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name ${ip_name}")

tcl_script.println(s"""
set_property -dict [list \\
CONFIG.HAS_TLAST {1} \\
CONFIG.TUSER_WIDTH {1} \\
] [get_ips ${ip_name}]
""")

tcl_script.println(s"generate_target {instantiation_template} [get_ips ${ip_name}]")
tcl_script.println("update_compile_order -fileset sources_1")
tcl_script.println(s"generate_target all [get_ips ${ip_name}]")
tcl_script.println(s"catch { config_ip_cache -export [get_ips -all ${ip_name}] }")
tcl_script.println(s"export_ip_user_files -of_objects [get_ips ${ip_name}] -no_script -sync -force -quiet")
tcl_script.println(s"create_ip_run [get_ips ${ip_name}]")

tcl_script.close()
}
generate_tcl_script()
}
31 changes: 30 additions & 1 deletion src/main/scala/wrapper/AXIStreamDataFIFO.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import chisel3.{BlackBox, _}
import chisel3.util._

import java.io.PrintWriter

class axis_data_fifo_0(width: Int) extends BlackBox {

class AXIStreamDataFifo(width: Int) extends BlackBox {
val io = IO(new Bundle {
val s_axis_aresetn = Input(Reset())
val s_axis_aclk = Input(Clock())
Expand All @@ -17,4 +19,31 @@ class axis_data_fifo_0(width: Int) extends BlackBox {
val m_axis_tlast = Output(Bool())
val m_axis_tuser = Output(Bool())
})

def generate_tcl_script(): Unit = {
val vivado_project_dir = "out/VivadoProject"
val ip_name = "AXIStreamDataFifo"
val ip_name_lower = ip_name.toLowerCase()

val tcl_script = new PrintWriter(s"${vivado_project_dir}/scripts/create_ip_${ip_name_lower}.tcl")

tcl_script.println(s"create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name ${ip_name}")

tcl_script.println(s"""
set_property -dict [list \\
CONFIG.HAS_TLAST {1} \\
CONFIG.TUSER_WIDTH {1} \\
] [get_ips ${ip_name}]
""")

tcl_script.println(s"generate_target {instantiation_template} [get_ips ${ip_name}]")
tcl_script.println("update_compile_order -fileset sources_1")
tcl_script.println(s"generate_target all [get_ips ${ip_name}]")
tcl_script.println(s"catch { config_ip_cache -export [get_ips -all ${ip_name}] }")
tcl_script.println(s"export_ip_user_files -of_objects [get_ips ${ip_name}] -no_script -sync -force -quiet")
tcl_script.println(s"create_ip_run [get_ips ${ip_name}]")

tcl_script.close()
}
generate_tcl_script()
}
73 changes: 72 additions & 1 deletion src/main/scala/wrapper/ClkWizWrapper.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,84 @@
import chisel3.{BlackBox, _}
import chisel3.util._

import java.io.PrintWriter

class clk_wiz_0 extends BlackBox {

class ClockingWizard(
clk_out1_freq: Int,
clk_out2_freq: Int = 0,
clk_out3_freq: Int = 0,
clk_out4_freq: Int = 0,
clk_out5_freq: Int = 0,
clk_out6_freq: Int = 0,
clk_out7_freq: Int = 0
) extends BlackBox {
val io = IO(new Bundle {
val clk_in1 = Input(Clock())
val reset = Input(Bool())
val locked = Output(Bool())
val clk_out1 = Output(Clock())
val clk_out2 = Output(Clock())
val clk_out3 = Output(Clock())
val clk_out4 = Output(Clock())
val clk_out5 = Output(Clock())
val clk_out6 = Output(Clock())
val clk_out7 = Output(Clock())
})

def generate_tcl_script(): Unit = {
val vivado_project_dir = "out/VivadoProject"
val ip_name = "ClockingWizard"
val ip_name_lower = ip_name.toLowerCase()

var num_out_clks = 1
if (clk_out2_freq > 0) {
num_out_clks += 1
}
if (clk_out3_freq > 0) {
num_out_clks += 1
}
if (clk_out4_freq > 0) {
num_out_clks += 1
}
if (clk_out5_freq > 0) {
num_out_clks += 1
}
if (clk_out6_freq > 0) {
num_out_clks += 1
}
if (clk_out7_freq > 0) {
num_out_clks += 1
}

val tcl_script = new PrintWriter(s"${vivado_project_dir}/scripts/create_ip_${ip_name_lower}.tcl")

tcl_script.println(s"create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name ${ip_name}")

tcl_script.println(s"""
set_property -dict [list \\
CONFIG.CLKOUT1_JITTER {125.247} \\
CONFIG.CLKOUT1_PHASE_ERROR {98.575} \\
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {${clk_out1_freq}} \\
CONFIG.CLKOUT2_JITTER {175.402} \\
CONFIG.CLKOUT2_PHASE_ERROR {98.575} \\
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {${clk_out2_freq}} \\
CONFIG.CLKOUT2_USED {${clk_out2_freq > 0}} \\
CONFIG.MMCM_CLKFBOUT_MULT_F {10.000} \\
CONFIG.MMCM_CLKOUT0_DIVIDE_F {8.000} \\
CONFIG.MMCM_CLKOUT1_DIVIDE {40} \\
CONFIG.NUM_OUT_CLKS {${num_out_clks}} \\
] [get_ips ${ip_name}]
""")

tcl_script.println(s"generate_target {instantiation_template} [get_ips ${ip_name}]")
tcl_script.println("update_compile_order -fileset sources_1")
tcl_script.println(s"generate_target all [get_ips ${ip_name}]")
tcl_script.println(s"catch { config_ip_cache -export [get_ips -all ${ip_name}] }")
tcl_script.println(s"export_ip_user_files -of_objects [get_ips ${ip_name}] -no_script -sync -force -quiet")
tcl_script.println(s"create_ip_run [get_ips ${ip_name}]")

tcl_script.close()
}
generate_tcl_script()
}

0 comments on commit 63bc04b

Please sign in to comment.