diff --git a/Makefile b/Makefile index 6e8f99af..5418b1b9 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ CLEAN_DIRS := doc SRC_DIR ?= . #SYSTEMC ?= $(SRC_DIR)/../../systemc/systemc-2.3.1 SYSCTESTS ?= $(addsuffix .sysctest,$(notdir $(basename $(wildcard $(SRC_DIR)/src/test/scala/SysCTest/*.scala)))) -CHISEL_JAR ?= $(SRC_DIR)/target/scala-2.10/chisel_2.10-2.3-SNAPSHOT.jar +CHISEL_JAR ?= $(SRC_DIR)/target/scala-2.11/chisel_2.11-2.3-SNAPSHOT.jar TEST_OUTPUT_DIR ?= ./test-outputs .PHONY: smoke publish-local check clean jenkins-build sysctest coverage scaladoc test diff --git a/patches/20150902/0001-Chisel-on-latest-version-implementation-SystemC-Deco.patch b/patches/20150902/0001-Chisel-on-latest-version-implementation-SystemC-Deco.patch new file mode 100644 index 00000000..c797310d --- /dev/null +++ b/patches/20150902/0001-Chisel-on-latest-version-implementation-SystemC-Deco.patch @@ -0,0 +1,405 @@ +From 4e7d87e3d532770d3d315a8be7ae751ae73a60c5 Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Thu, 27 Aug 2015 21:46:20 -0300 +Subject: [PATCH 1/7] Chisel (on latest version) implementation: SystemC + Decoupled and Template file (need to be tested). + +--- + src/main/resources/template_cpp.txt | 27 +++++++++ + src/main/resources/template_h.txt | 58 ++++++++++++++++++++ + src/main/scala/SCWrapper.scala | 106 +++++++++++++++++++++--------------- + src/main/scala/SysC.scala | 34 +++++++----- + 4 files changed, 169 insertions(+), 56 deletions(-) + create mode 100644 src/main/resources/template_cpp.txt + create mode 100644 src/main/resources/template_h.txt + +diff --git a/src/main/resources/template_cpp.txt b/src/main/resources/template_cpp.txt +new file mode 100644 +index 0000000..1996287 +--- /dev/null ++++ b/src/main/resources/template_cpp.txt +@@ -0,0 +1,27 @@ ++#include "{!name!}.h" ++ ++void {!name!}::input_thread(void){ ++ while(true){ ++// wait(data_written_event); ++ {!input_thread!} ++ {!set_valid_ready!} ++ //Clock Lo ++ c->clock_lo(reset); ++ wait(Step); ++// data_read_event.notify(SC_ZERO_TIME); ++ } ++} ++ ++void {!name!}::output_thread(void){ ++// data_written_event.notify(SC_ZERO_TIME); ++ while(true){ ++ wait(data_read_event); ++ {!output_thread!} ++ {!reset_valid_ready!} ++ //Clock Hi ++ c->clock_hi(reset); ++ wait(Step); ++// data_written_event.notify(SC_ZERO_TIME); ++ } ++} ++ +diff --git a/src/main/resources/template_h.txt b/src/main/resources/template_h.txt +new file mode 100644 +index 0000000..f1f4644 +--- /dev/null ++++ b/src/main/resources/template_h.txt +@@ -0,0 +1,58 @@ ++#ifndef __{!name!}__ ++#define __{!name!}__ ++ ++#include ++#include "{!header_file!}" ++ ++// ======================================== ++// dat_t needs to have this operator defined, so that ++// I'm allowed to use it with System C. ++// But be warned: I don't quite know what I ++// am doing. ++// ======================================== ++template ++inline ostream& operator << (ostream& os, const dat_t& arg){ ++ return os; ++} ++ ++SC_MODULE({!name!}){ ++ {!component_type!}* c; ++ ++ // in ports ++ {!input_ports!} ++ // out ports ++ {!output_ports!} ++ SC_HAS_PROCESS({!name!}); ++ {!name!}(sc_module_name a_name, sc_time _step) ++ : sc_module(a_name), Step(_step) ++ {!sctor_list!} ++ { ++ // Initialize Component, Clock in RESET ++ c = new {!component_type!}(); ++ c->init(); ++ Step = Step/2; ++ ++ // Clock Initialization? Don't understand what this is for. Copied from emulator. ++ for(int i = 0; i < 5; i++) { ++ dat_t<1> reset = LIT<1>(1); ++ c->clock_lo(reset); ++ c->clock_hi(reset); ++ } ++ ++ //Register Thread ++ SC_THREAD(input_thread); ++// {!sensitive_list!} ++ SC_THREAD(output_thread); ++ } ++ ++ void input_thread(void); ++ void output_thread(void); ++ ++// sc_event data_read_event; ++// sc_event data_written_event; ++ dat_t<1> reset = LIT<1>(0); ++ dat_t<1> set = LIT<1>(1); ++ sc_time Step; ++}; ++ ++#endif //__{!name!}__ +diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala +index d1d659d..2d58441 100644 +--- a/src/main/scala/SCWrapper.scala ++++ b/src/main/scala/SCWrapper.scala +@@ -54,21 +54,21 @@ object SCWrapper { + + def example_component_def(): ComponentDef = { + val cdef = new ComponentDef("GCD_t", "GCD") +- cdef.entries += new CEntry("a", true, "dat_t<1>", "GCD__io_a", "GCD__io_r1", "GCD__io_v1") +- cdef.entries += new CEntry("z", false, "dat_t<1>", "GCD__io_z", "GCD__io_rz", "GCD__io_vz") ++ cdef.entries += new CEntry("a", true, "dat_t<1>", 1, "GCD__io_a", "GCD__io_r1", "GCD__io_v1") ++ cdef.entries += new CEntry("z", false, "dat_t<1>", 1, "GCD__io_z", "GCD__io_rz", "GCD__io_vz") + cdef + } + + def example_component_def2(): ComponentDef = { + val cdef = new ComponentDef("AddFilter_t", "AddFilter") +- cdef.entries += new CEntry("a", true, "dat_t<16>", "AddFilter__io_a", "AddFilter__io_ar", "AddFilter__io_av") +- cdef.entries += new CEntry("b", false, "dat_t<16>", "AddFilter__io_b", "AddFilter__io_br", "AddFilter__io_bv") ++ cdef.entries += new CEntry("a", true, "dat_t<16>", 16, "AddFilter__io_a", "AddFilter__io_ar", "AddFilter__io_av") ++ cdef.entries += new CEntry("b", false, "dat_t<16>", 16, "AddFilter__io_b", "AddFilter__io_br", "AddFilter__io_bv") + cdef + } + +- def genwrapper(c: ComponentDef, filename: String) { ++ def genwrapper(c: ComponentDef, filename: String, templatefile: String) { + //Read in template +- val template = read_resource("template.txt") ++ val template = read_resource(templatefile) + + //Generate replacements + val replacements = generate_replacements(c) +@@ -81,9 +81,9 @@ object SCWrapper { + System.out.println(filled) + } + +- def genwrapper(c: ComponentDef, filewriter: java.io.FileWriter){ ++ def genwrapper(c: ComponentDef, filewriter: java.io.FileWriter, templatefile: String){ + //Read in template +- val template = read_resource("template.txt") ++ val template = read_resource(templatefile) + + //Generate replacements + val replacements = generate_replacements(c) +@@ -106,62 +106,80 @@ object SCWrapper { + replacements += (("name", "SCWrapped" + c.name)) + replacements += (("component_type", c.ctype)) + +- //I/O Fifos ++ //I/O Ports + /*begin*/{ +- var input_fifos = "" +- var output_fifos = "" ++ var input_ports = "" ++ var output_ports = "" ++ var sctor_list = "" ++ var input_thread = "" ++ var output_thread = "" ++ + for( e <- c.entries) { +- val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) ++ val decl_in = "sc_in > %s__io_%s;\n ".format(e.cwidth, c.name, e.name) ++ val decl_out = "sc_out > %s__io_%s;\n ".format(e.cwidth, c.name, e.name) ++ val thread_in = "c->%s__io_%s = LIT<%s>(%s__io_%s->read());\n ".format(c.name, e.name, e.cwidth, c.name, e.name) ++ val thread_out = "%s__io_%s->write(c->%s__io_%s.to_ulong());\n ".format(c.name, e.name, c.name, e.name) ++ //val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) + if(e.is_input) { +- input_fifos += decl ++ input_ports += decl_in ++ sctor_list += ", %s__io_%s(\"%s\")".format(c.name, e.name, e.name) ++ //sensitive_list += " << %s__io_%s".format(c.name, e.name) ++ input_thread += thread_in + } else { +- output_fifos += decl ++ output_ports += decl_out ++ sctor_list += ", %s__io_%s(\"%s\")".format(c.name, e.name, e.name) ++ output_thread += thread_out + } + } +- replacements += (("input_fifos", input_fifos)) +- replacements += (("output_fifos", output_fifos)) ++ replacements += (("input_ports", input_ports)) ++ replacements += (("output_ports", output_ports)) ++ replacements += (("sctor_list", sctor_list)) ++ //sensitive_list += ";" ++ //replacements += (("sensitive_list", sensitive_list)) ++ replacements += (("input_thread", input_thread)) ++ replacements += (("output_thread", output_thread)) + } + +- /*Initialize output fifos*/{ +- //Pull out output fifos +- val fifos = ArrayBuffer[CEntry](); ++ /*Initialize output ports*/{ ++ //Pull out output ports ++ val ports = ArrayBuffer[CEntry](); + for(e <- c.entries) { + if(!e.is_input) { +- fifos += e; ++ ports += e; + } + } + //Initialize + var init = ""; +- for( i <- 0 until fifos.size) { +- init += "%s = new sc_fifo<%s >(1);\n ".format(fifos(i).name, fifos(i).ctype) ++ for( i <- 0 until ports.size) { ++ init += "%s = new sc_fifo**???**<%s >(1);\n ".format(ports(i).name, ports(i).ctype) + } + replacements += (("init_output_fifos", init)) + } + + /*Check input queues*/{ +- //Pull out input fifos ++ //Pull out input ports + val dvar = ArrayBuffer[String]() + val fvar = ArrayBuffer[String]() +- val fifos = ArrayBuffer[CEntry]() ++ val ports = ArrayBuffer[CEntry]() + for( e <- c.entries) { + if(e.is_input) { + dvar += genvar("dat") + fvar += genvar("filled") +- fifos += e ++ ports += e + } + } + //Initialize + var init = "" + var fill = "" + var check = "" +- for( i <- 0 until fifos.size) { +- val ctype = fifos(i).ctype ++ for( i <- 0 until ports.size) { ++ val ctype = ports(i).ctype + val data = dvar(i) + val filled = fvar(i) +- val in = fifos(i).name +- val in_data = fifos(i).data +- val ready = fifos(i).ready +- val valid = fifos(i).valid ++ val in = ports(i).name ++ val in_data = ports(i).data ++ val ready = ports(i).ready ++ val valid = ports(i).valid + init += "%s %s;\n ".format(ctype, data) + init += "int %s = 0;\n ".format(filled) + fill += "if(!%s){%s = %s->nb_read(%s);}\n "format(filled, filled, in, data) +@@ -183,22 +201,22 @@ object SCWrapper { + } + + /*Check Output Queues*/{ +- //Pull out output fifos +- val fifos = ArrayBuffer[CEntry]() ++ //Pull out output ports ++ val ports = ArrayBuffer[CEntry]() + for (e <- c.entries) { + if(!e.is_input) { +- fifos += e ++ ports += e + } + } + //Check + var check = "" + var valid_output = ""; +- for(i <- 0 until fifos.size) { +- val ctype = fifos(i).ctype +- val valid = fifos(i).valid +- val data = fifos(i).data +- val ready = fifos(i).ready +- val out = fifos(i).name ++ for(i <- 0 until ports.size) { ++ val ctype = ports(i).ctype ++ val valid = ports(i).valid ++ val data = ports(i).data ++ val ready = ports(i).ready ++ val out = ports(i).name + check += "c->%s = LIT<1>(%s->num_free() > 0);\n "format(ready, out) + // Is this a structured data-type? + if (ctype == data) { +@@ -220,11 +238,11 @@ object SCWrapper { + + // If we have structured FIFO elements, we need to generate the struct definitions + // and the ostream "<<" definition to keep SystemC happy. +- val ostream_lsh = ArrayBuffer[String]() ++/* val ostream_lsh = ArrayBuffer[String]() + for((name, struct) <- c.structs) { + ostream_lsh += struct.toString + "inline ostream& operator << (ostream& os, const %s& arg){ return os; }\n".format(name) + } +- replacements += (("ostream_lsh", ostream_lsh.mkString("\n"))) ++ replacements += (("ostream_lsh", ostream_lsh.mkString("\n"))) */ + replacements + } + +@@ -309,10 +327,11 @@ object SCWrapper { + } + } + +-class CEntry(a_name: String, input: Boolean, a_type: String, a_data: String, a_ready: String, a_valid: String) { ++class CEntry(a_name: String, input: Boolean, a_type: String, a_width: Int, a_data: String, a_ready: String, a_valid: String) { + val name = a_name + val is_input = input + val ctype = a_type ++ val cwidth = a_width + val data = a_data + val ready = a_ready + val valid = a_valid +@@ -321,6 +340,7 @@ class CEntry(a_name: String, input: Boolean, a_type: String, a_data: String, a_r + name + " " + + is_input + " " + + ctype + " " + ++ cwidth + " " + + data + " " + + ready + " " + + valid +diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala +index 566a3cf..73c17e1 100644 +--- a/src/main/scala/SysC.scala ++++ b/src/main/scala/SysC.scala +@@ -30,9 +30,7 @@ + + package Chisel + +-/** If we have structured/aggregate types as top-level ports, we define suitable structures +- * for encapsulating their components, in order to treat them as sc_fifo elements. +- */ ++ + class SysCBackend extends CppBackend { + override def elaborate(c: Module): Unit = { + super.elaborate(c) +@@ -51,29 +49,35 @@ class SysCBackend extends CppBackend { + case bits: Bits => { + val is_input = bits.dir == INPUT + val vtype = "dat_t<" + bits.width + ">" // direct use of width here? +- val entry = new CEntry(name, is_input, vtype, bits.name, delt.ready.name, delt.valid.name) ++ val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, delt.ready.name, delt.valid.name) + cdef.entries += (entry) + } + case aggregate: Aggregate => { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) + if (inputs.length > 0) { +- val aName = "cs_" + aggregate.name + "_i" +- cdef.structs(aName)= new CStruct(aName, inputs) +- val entry = new CEntry(name, true, aName, aName, delt.ready.name, delt.valid.name) ++ val aName = "dat_t<" + aggregate.width + ">" //"cs_" + aggregate.name + "_i" ++ //cdef.structs(aName)= new CStruct(aName, inputs) ++ val entry = new CEntry(name, true, aName, aggregate.width, aggregate.name, delt.ready.name, delt.valid.name) + cdef.entries += (entry) + } + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { +- val aName = "cs_" + aggregate.name + "_o" +- cdef.structs(aName) = new CStruct(aName, outputs) +- val entry = new CEntry(name, false, aName, aName, delt.ready.name, delt.valid.name) ++ val aName = "dat_t<" + aggregate.width + ">" //"cs_" + aggregate.name + "_o" ++ //cdef.structs(aName) = new CStruct(aName, outputs) ++ val entry = new CEntry(name, false, aName, aggregate.width, aggregate.name, delt.ready.name, delt.valid.name) + cdef.entries += (entry) + } + } + case _ => badElements(name) = elt + } + } ++ case bits: Bits => { ++ val is_input = bits.dir == INPUT ++ val vtype = "dat_t<" + bits.width + ">" // direct use of width here? ++ val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, "ready", "valid") ++ cdef.entries += (entry) ++ } + case _ => badElements(name) = elt + } + } +@@ -93,9 +97,13 @@ class SysCBackend extends CppBackend { + //Print out the component definition. + println(cdef) + +- //Generate the file. +- val out_p = createOutputFile("SCWrapped" + c.name + ".cpp"); +- SCWrapper.genwrapper(cdef, out_p) ++ //Generate SCWrapped files ++ val out_h = createOutputFile("SCWrapped" + c.name + ".h"); ++ val template_h = "template_h.txt" ++ SCWrapper.genwrapper(cdef, out_h, template_h) ++ val out_cpp = createOutputFile("SCWrapped" + c.name + ".cpp"); ++ val template_cpp = "template_cpp.txt" ++ SCWrapper.genwrapper(cdef, out_cpp, template_cpp) + } + } + } +-- +2.1.0 + diff --git a/patches/20150902/0002-Updated-Sysc.scala-not-funcional-yet.-Fix-Chisel-ver.patch b/patches/20150902/0002-Updated-Sysc.scala-not-funcional-yet.-Fix-Chisel-ver.patch new file mode 100644 index 00000000..bbb2e7e8 --- /dev/null +++ b/patches/20150902/0002-Updated-Sysc.scala-not-funcional-yet.-Fix-Chisel-ver.patch @@ -0,0 +1,109 @@ +From 747f26151cb26ec40e6aa07529584b99c32bc1bd Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Sat, 29 Aug 2015 20:07:40 -0300 +Subject: [PATCH 2/7] Updated Sysc.scala, not funcional yet. Fix Chisel version + in Makefile. + +--- + Makefile | 2 +- + src/main/resources/template_cpp.txt | 6 +++--- + src/main/resources/template_h.txt | 1 - + src/main/scala/SysC.scala | 30 ++++++++++++++++++++---------- + 4 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/Makefile b/Makefile +index 6e8f99a..5418b1b 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ CLEAN_DIRS := doc + SRC_DIR ?= . + #SYSTEMC ?= $(SRC_DIR)/../../systemc/systemc-2.3.1 + SYSCTESTS ?= $(addsuffix .sysctest,$(notdir $(basename $(wildcard $(SRC_DIR)/src/test/scala/SysCTest/*.scala)))) +-CHISEL_JAR ?= $(SRC_DIR)/target/scala-2.10/chisel_2.10-2.3-SNAPSHOT.jar ++CHISEL_JAR ?= $(SRC_DIR)/target/scala-2.11/chisel_2.11-2.3-SNAPSHOT.jar + TEST_OUTPUT_DIR ?= ./test-outputs + + .PHONY: smoke publish-local check clean jenkins-build sysctest coverage scaladoc test +diff --git a/src/main/resources/template_cpp.txt b/src/main/resources/template_cpp.txt +index 1996287..948ef66 100644 +--- a/src/main/resources/template_cpp.txt ++++ b/src/main/resources/template_cpp.txt +@@ -4,7 +4,7 @@ void {!name!}::input_thread(void){ + while(true){ + // wait(data_written_event); + {!input_thread!} +- {!set_valid_ready!} ++// {!set_valid_ready!} + //Clock Lo + c->clock_lo(reset); + wait(Step); +@@ -15,9 +15,9 @@ void {!name!}::input_thread(void){ + void {!name!}::output_thread(void){ + // data_written_event.notify(SC_ZERO_TIME); + while(true){ +- wait(data_read_event); ++// wait(data_read_event); + {!output_thread!} +- {!reset_valid_ready!} ++// {!reset_valid_ready!} + //Clock Hi + c->clock_hi(reset); + wait(Step); +diff --git a/src/main/resources/template_h.txt b/src/main/resources/template_h.txt +index f1f4644..257cd96 100644 +--- a/src/main/resources/template_h.txt ++++ b/src/main/resources/template_h.txt +@@ -34,7 +34,6 @@ SC_MODULE({!name!}){ + + // Clock Initialization? Don't understand what this is for. Copied from emulator. + for(int i = 0; i < 5; i++) { +- dat_t<1> reset = LIT<1>(1); + c->clock_lo(reset); + c->clock_hi(reset); + } +diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala +index 73c17e1..84534c2 100644 +--- a/src/main/scala/SysC.scala ++++ b/src/main/scala/SysC.scala +@@ -55,18 +55,28 @@ class SysCBackend extends CppBackend { + case aggregate: Aggregate => { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) +- if (inputs.length > 0) { +- val aName = "dat_t<" + aggregate.width + ">" //"cs_" + aggregate.name + "_i" +- //cdef.structs(aName)= new CStruct(aName, inputs) +- val entry = new CEntry(name, true, aName, aggregate.width, aggregate.name, delt.ready.name, delt.valid.name) +- cdef.entries += (entry) +- } ++ // if (inputs.length > 0) { ++ val l = inputs.length ++ for (i <- 1 to l) { ++ //val aName = "cs_" + aggregate.name + "_i" ++ val cmpnt = aggregate.flatten.map(_._2) ++ val vtype = "dat_t<" + 1 + ">" ++ //cdef.structs(aName)= new CStruct(aName, inputs) ++ //val entry = new CEntry(name, true, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) ++ val entry = new CEntry(name, true, vtype, 1, aggregate.name, "ready", "valid") ++ cdef.entries += (entry) ++ } ++ //} + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { +- val aName = "dat_t<" + aggregate.width + ">" //"cs_" + aggregate.name + "_o" +- //cdef.structs(aName) = new CStruct(aName, outputs) +- val entry = new CEntry(name, false, aName, aggregate.width, aggregate.name, delt.ready.name, delt.valid.name) +- cdef.entries += (entry) ++ for (t <- 0 until outputs.length) { ++ //val aName = "cs_" + aggregate.name + "_o" ++ val vtype = "dat_t<" + 1 + ">" ++ //cdef.structs(aName) = new CStruct(aName, outputs) ++ //val entry = new CEntry(name, false, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) ++ val entry = new CEntry(name, false, vtype, 1, aggregate.name, "ready", "valid") ++ cdef.entries += (entry) ++ } + } + } + case _ => badElements(name) = elt +-- +2.1.0 + diff --git a/patches/20150902/0003-SystemC-backend-running-ok-for-Decoupled-protocol-ne.patch b/patches/20150902/0003-SystemC-backend-running-ok-for-Decoupled-protocol-ne.patch new file mode 100644 index 00000000..07169482 --- /dev/null +++ b/patches/20150902/0003-SystemC-backend-running-ok-for-Decoupled-protocol-ne.patch @@ -0,0 +1,125 @@ +From 34d69817deaaf22f712d0b34425ecae172b686cb Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Sun, 30 Aug 2015 21:33:11 -0300 +Subject: [PATCH 3/7] SystemC backend running ok for Decoupled protocol (needs + to be teted with Sodor). + +--- + src/main/resources/template_cpp.txt | 2 -- + src/main/scala/SCWrapper.scala | 22 ++++++++++++++++------ + src/main/scala/SysC.scala | 30 ++++++++++++++---------------- + 3 files changed, 30 insertions(+), 24 deletions(-) + +diff --git a/src/main/resources/template_cpp.txt b/src/main/resources/template_cpp.txt +index 948ef66..359adff 100644 +--- a/src/main/resources/template_cpp.txt ++++ b/src/main/resources/template_cpp.txt +@@ -4,7 +4,6 @@ void {!name!}::input_thread(void){ + while(true){ + // wait(data_written_event); + {!input_thread!} +-// {!set_valid_ready!} + //Clock Lo + c->clock_lo(reset); + wait(Step); +@@ -17,7 +16,6 @@ void {!name!}::output_thread(void){ + while(true){ + // wait(data_read_event); + {!output_thread!} +-// {!reset_valid_ready!} + //Clock Hi + c->clock_hi(reset); + wait(Step); +diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala +index 2d58441..7a9d814 100644 +--- a/src/main/scala/SCWrapper.scala ++++ b/src/main/scala/SCWrapper.scala +@@ -115,22 +115,32 @@ object SCWrapper { + var output_thread = "" + + for( e <- c.entries) { +- val decl_in = "sc_in > %s__io_%s;\n ".format(e.cwidth, c.name, e.name) +- val decl_out = "sc_out > %s__io_%s;\n ".format(e.cwidth, c.name, e.name) +- val thread_in = "c->%s__io_%s = LIT<%s>(%s__io_%s->read());\n ".format(c.name, e.name, e.cwidth, c.name, e.name) +- val thread_out = "%s__io_%s->write(c->%s__io_%s.to_ulong());\n ".format(c.name, e.name, c.name, e.name) ++ val decl_in = "sc_in > %s;\n ".format(e.cwidth, e.data) ++ val decl_out = "sc_out > %s;\n ".format(e.cwidth, e.data) ++ val thread_in = "c->%s = LIT<%s>(%s->read().to_uint64());\n ".format(e.data, e.cwidth, e.data) ++ val thread_out = "%s->write(c->%s.to_ulong());\n ".format(e.data, e.data) + //val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) + if(e.is_input) { + input_ports += decl_in +- sctor_list += ", %s__io_%s(\"%s\")".format(c.name, e.name, e.name) ++ sctor_list += ", %s(\"%s\")\n ".format(e.data, e.data) + //sensitive_list += " << %s__io_%s".format(c.name, e.name) + input_thread += thread_in + } else { + output_ports += decl_out +- sctor_list += ", %s__io_%s(\"%s\")".format(c.name, e.name, e.name) ++ sctor_list += ", %s(\"%s\")\n ".format(e.data, e.data) + output_thread += thread_out + } + } ++ output_ports += "sc_out > %s__io_in_ready;\n ".format(c.name) ++ output_ports += "sc_out > %s__io_out_valid;\n ".format(c.name) ++ sctor_list += ", %s__io_in_ready(\"%s__io_in_ready\")\n ".format(c.name, c.name) ++ sctor_list += ", %s__io_out_valid(\"%s__io_out_valid\")".format(c.name, c.name) ++ input_thread += "c->%s__io_in_valid = set;\n ".format(c.name) ++ input_thread += "c->%s__io_out_ready = set;\n ".format(c.name) ++ output_thread += "%s__io_out_valid->write(c->%s__io_out_valid.to_ulong());\n ".format(c.name, c.name) ++ output_thread += "%s__io_in_ready->write(c->%s__io_in_ready.to_ulong());\n ".format(c.name, c.name) ++ output_thread += "c->%s__io_in_valid = reset;\n ".format(c.name) ++ output_thread += "c->%s__io_out_ready = reset;".format(c.name) + replacements += (("input_ports", input_ports)) + replacements += (("output_ports", output_ports)) + replacements += (("sctor_list", sctor_list)) +diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala +index 84534c2..e1c8f39 100644 +--- a/src/main/scala/SysC.scala ++++ b/src/main/scala/SysC.scala +@@ -55,28 +55,26 @@ class SysCBackend extends CppBackend { + case aggregate: Aggregate => { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) +- // if (inputs.length > 0) { +- val l = inputs.length +- for (i <- 1 to l) { +- //val aName = "cs_" + aggregate.name + "_i" +- val cmpnt = aggregate.flatten.map(_._2) +- val vtype = "dat_t<" + 1 + ">" +- //cdef.structs(aName)= new CStruct(aName, inputs) +- //val entry = new CEntry(name, true, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) +- val entry = new CEntry(name, true, vtype, 1, aggregate.name, "ready", "valid") ++ if (inputs.length > 0) { ++ for (in <- inputs) { ++ val vtype = "dat_t<" + in._2.width + ">" ++ val entry = new CEntry(name, true, vtype, in._2.width, in._2.name, "ready", "valid") + cdef.entries += (entry) + } +- //} ++ //val aName = "cs_" + aggregate.name + "_i" ++ //cdef.structs(aName)= new CStruct(aName, inputs) ++ //val entry = new CEntry(name, true, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) ++ } + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { +- for (t <- 0 until outputs.length) { +- //val aName = "cs_" + aggregate.name + "_o" +- val vtype = "dat_t<" + 1 + ">" +- //cdef.structs(aName) = new CStruct(aName, outputs) +- //val entry = new CEntry(name, false, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) +- val entry = new CEntry(name, false, vtype, 1, aggregate.name, "ready", "valid") ++ for (out <- outputs) { ++ val vtype = "dat_t<" + out._2.width + ">" ++ val entry = new CEntry(name, false, vtype, out._2.width, out._2.name, "ready", "valid") + cdef.entries += (entry) + } ++ //val aName = "cs_" + aggregate.name + "_o" ++ //cdef.structs(aName) = new CStruct(aName, outputs) ++ //val entry = new CEntry(name, false, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) + } + } + case _ => badElements(name) = elt +-- +2.1.0 + diff --git a/patches/20150902/0004-Updated-SysemC-backend-fix-generation-of-no-decouple.patch b/patches/20150902/0004-Updated-SysemC-backend-fix-generation-of-no-decouple.patch new file mode 100644 index 00000000..477932e0 --- /dev/null +++ b/patches/20150902/0004-Updated-SysemC-backend-fix-generation-of-no-decouple.patch @@ -0,0 +1,41 @@ +From 0ebce712beea0e1f6ee0dfcbb22bee90906c1f3a Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Mon, 31 Aug 2015 12:07:08 -0300 +Subject: [PATCH 4/7] Updated SysemC backend: fix generation of no decoupled + modules code + +--- + src/main/scala/SysC.scala | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala +index e1c8f39..17b8301 100644 +--- a/src/main/scala/SysC.scala ++++ b/src/main/scala/SysC.scala +@@ -51,6 +51,7 @@ class SysCBackend extends CppBackend { + val vtype = "dat_t<" + bits.width + ">" // direct use of width here? + val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, delt.ready.name, delt.valid.name) + cdef.entries += (entry) ++ cdef.valid_ready = true + } + case aggregate: Aggregate => { + // Collect all the inputs and outputs. +@@ -76,6 +77,7 @@ class SysCBackend extends CppBackend { + //cdef.structs(aName) = new CStruct(aName, outputs) + //val entry = new CEntry(name, false, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) + } ++ cdef.valid_ready = true + } + case _ => badElements(name) = elt + } +@@ -85,6 +87,7 @@ class SysCBackend extends CppBackend { + val vtype = "dat_t<" + bits.width + ">" // direct use of width here? + val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, "ready", "valid") + cdef.entries += (entry) ++ cdef.valid_ready = false + } + case _ => badElements(name) = elt + } +-- +2.1.0 + diff --git a/patches/20150902/0005-Updadted-Chisel-SCWrapper.scala.patch b/patches/20150902/0005-Updadted-Chisel-SCWrapper.scala.patch new file mode 100644 index 00000000..a04ab6f0 --- /dev/null +++ b/patches/20150902/0005-Updadted-Chisel-SCWrapper.scala.patch @@ -0,0 +1,53 @@ +From 920384e827ccda78d7e06915fa32e2c4d462789e Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Mon, 31 Aug 2015 18:51:08 -0300 +Subject: [PATCH 5/7] Updadted Chisel SCWrapper.scala. + +--- + src/main/scala/SCWrapper.scala | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala +index 7a9d814..104885a 100644 +--- a/src/main/scala/SCWrapper.scala ++++ b/src/main/scala/SCWrapper.scala +@@ -131,16 +131,18 @@ object SCWrapper { + output_thread += thread_out + } + } +- output_ports += "sc_out > %s__io_in_ready;\n ".format(c.name) +- output_ports += "sc_out > %s__io_out_valid;\n ".format(c.name) +- sctor_list += ", %s__io_in_ready(\"%s__io_in_ready\")\n ".format(c.name, c.name) +- sctor_list += ", %s__io_out_valid(\"%s__io_out_valid\")".format(c.name, c.name) +- input_thread += "c->%s__io_in_valid = set;\n ".format(c.name) +- input_thread += "c->%s__io_out_ready = set;\n ".format(c.name) +- output_thread += "%s__io_out_valid->write(c->%s__io_out_valid.to_ulong());\n ".format(c.name, c.name) +- output_thread += "%s__io_in_ready->write(c->%s__io_in_ready.to_ulong());\n ".format(c.name, c.name) +- output_thread += "c->%s__io_in_valid = reset;\n ".format(c.name) +- output_thread += "c->%s__io_out_ready = reset;".format(c.name) ++ if (c.valid_ready == true){ ++ sctor_list += ", %s__io_in_ready(\"%s__io_in_ready\")\n ".format(c.name, c.name) ++ sctor_list += ", %s__io_out_valid(\"%s__io_out_valid\")".format(c.name, c.name) ++ output_ports += "sc_out > %s__io_in_ready;\n ".format(c.name) ++ output_ports += "sc_out > %s__io_out_valid;\n ".format(c.name) ++ input_thread += "c->%s__io_in_valid = set;\n ".format(c.name) ++ input_thread += "c->%s__io_out_ready = set;\n ".format(c.name) ++ output_thread += "%s__io_out_valid->write(c->%s__io_out_valid.to_ulong());\n ".format(c.name, c.name) ++ output_thread += "%s__io_in_ready->write(c->%s__io_in_ready.to_ulong());\n ".format(c.name, c.name) ++ output_thread += "c->%s__io_in_valid = reset;\n ".format(c.name) ++ output_thread += "c->%s__io_out_ready = reset;".format(c.name) ++ } + replacements += (("input_ports", input_ports)) + replacements += (("output_ports", output_ports)) + replacements += (("sctor_list", sctor_list)) +@@ -360,6 +362,7 @@ class CEntry(a_name: String, input: Boolean, a_type: String, a_width: Int, a_dat + class ComponentDef(a_type: String, a_name: String) { + val ctype: String = a_type + val name: String = a_name ++ var valid_ready: Boolean = false + val entries = ArrayBuffer[CEntry]() + val structs = scala.collection.mutable.LinkedHashMap[String, CStruct]() + +-- +2.1.0 + diff --git a/patches/20150902/0006-Fixes-and-Updates-into-SystemC-Backand-satus-ok-test.patch b/patches/20150902/0006-Fixes-and-Updates-into-SystemC-Backand-satus-ok-test.patch new file mode 100644 index 00000000..9e6f771b --- /dev/null +++ b/patches/20150902/0006-Fixes-and-Updates-into-SystemC-Backand-satus-ok-test.patch @@ -0,0 +1,249 @@ +From be49342cf2945d343e70abfcae6f50e6a535ade2 Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Tue, 1 Sep 2015 15:49:53 -0300 +Subject: [PATCH 6/7] Fixes and Updates into SystemC Backand: satus ok, tested + with AllTypes + FullAdder{Decoupled}. + +--- + src/main/resources/template_cpp.txt | 5 --- + src/main/resources/template_h.txt | 3 -- + src/main/scala/SCWrapper.scala | 51 +++++++++++++------------- + src/main/scala/SysC.scala | 71 +++++++++++++++++++++++++++---------- + 4 files changed, 79 insertions(+), 51 deletions(-) + +diff --git a/src/main/resources/template_cpp.txt b/src/main/resources/template_cpp.txt +index 359adff..13f6076 100644 +--- a/src/main/resources/template_cpp.txt ++++ b/src/main/resources/template_cpp.txt +@@ -2,24 +2,19 @@ + + void {!name!}::input_thread(void){ + while(true){ +-// wait(data_written_event); + {!input_thread!} + //Clock Lo + c->clock_lo(reset); + wait(Step); +-// data_read_event.notify(SC_ZERO_TIME); + } + } + + void {!name!}::output_thread(void){ +-// data_written_event.notify(SC_ZERO_TIME); + while(true){ +-// wait(data_read_event); + {!output_thread!} + //Clock Hi + c->clock_hi(reset); + wait(Step); +-// data_written_event.notify(SC_ZERO_TIME); + } + } + +diff --git a/src/main/resources/template_h.txt b/src/main/resources/template_h.txt +index 257cd96..020ac13 100644 +--- a/src/main/resources/template_h.txt ++++ b/src/main/resources/template_h.txt +@@ -40,15 +40,12 @@ SC_MODULE({!name!}){ + + //Register Thread + SC_THREAD(input_thread); +-// {!sensitive_list!} + SC_THREAD(output_thread); + } + + void input_thread(void); + void output_thread(void); + +-// sc_event data_read_event; +-// sc_event data_written_event; + dat_t<1> reset = LIT<1>(0); + dat_t<1> set = LIT<1>(1); + sc_time Step; +diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala +index 104885a..e5d2993 100644 +--- a/src/main/scala/SCWrapper.scala ++++ b/src/main/scala/SCWrapper.scala +@@ -54,15 +54,15 @@ object SCWrapper { + + def example_component_def(): ComponentDef = { + val cdef = new ComponentDef("GCD_t", "GCD") +- cdef.entries += new CEntry("a", true, "dat_t<1>", 1, "GCD__io_a", "GCD__io_r1", "GCD__io_v1") +- cdef.entries += new CEntry("z", false, "dat_t<1>", 1, "GCD__io_z", "GCD__io_rz", "GCD__io_vz") ++ cdef.entries += new CEntry("a", true, "dat_t<1>", "dat_t<1>", 1, "GCD__io_a", "GCD__io_r1", "GCD__io_v1") ++ cdef.entries += new CEntry("z", false, "dat_t<1>", "dat_t<1>", 1, "GCD__io_z", "GCD__io_rz", "GCD__io_vz") + cdef + } + + def example_component_def2(): ComponentDef = { + val cdef = new ComponentDef("AddFilter_t", "AddFilter") +- cdef.entries += new CEntry("a", true, "dat_t<16>", 16, "AddFilter__io_a", "AddFilter__io_ar", "AddFilter__io_av") +- cdef.entries += new CEntry("b", false, "dat_t<16>", 16, "AddFilter__io_b", "AddFilter__io_br", "AddFilter__io_bv") ++ cdef.entries += new CEntry("a", true, "dat_t<16>", "dat_t<1>", 16, "AddFilter__io_a", "AddFilter__io_ar", "AddFilter__io_av") ++ cdef.entries += new CEntry("b", false, "dat_t<16>", "dat_t<1>", 16, "AddFilter__io_b", "AddFilter__io_br", "AddFilter__io_bv") + cdef + } + +@@ -115,10 +115,10 @@ object SCWrapper { + var output_thread = "" + + for( e <- c.entries) { +- val decl_in = "sc_in > %s;\n ".format(e.cwidth, e.data) +- val decl_out = "sc_out > %s;\n ".format(e.cwidth, e.data) +- val thread_in = "c->%s = LIT<%s>(%s->read().to_uint64());\n ".format(e.data, e.cwidth, e.data) +- val thread_out = "%s->write(c->%s.to_ulong());\n ".format(e.data, e.data) ++ val decl_in = "sc_in<%s > %s;\n ".format(e.ctype, e.data) ++ val decl_out = "sc_out<%s > %s;\n ".format(e.ctype, e.data) ++ val thread_in = "c->%s = LIT<%s>(%s->read()%s);\n ".format(e.data, e.cwidth, e.data, e.ccast) ++ val thread_out = "%s->write(c->%s%s);\n ".format(e.data, e.data, e.ccast) + //val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) + if(e.is_input) { + input_ports += decl_in +@@ -339,24 +339,25 @@ object SCWrapper { + } + } + +-class CEntry(a_name: String, input: Boolean, a_type: String, a_width: Int, a_data: String, a_ready: String, a_valid: String) { +- val name = a_name +- val is_input = input +- val ctype = a_type +- val cwidth = a_width +- val data = a_data +- val ready = a_ready +- val valid = a_valid ++class CEntry(a_name: String, input: Boolean, a_type: String, a_cast: String, a_width: Int, a_data: String, a_ready: String, a_valid: String) { ++ val name = a_name ++ val is_input = input ++ val ctype = a_type ++ val ccast = a_cast ++ val cwidth = a_width ++ val data = a_data ++ val ready = a_ready ++ val valid = a_valid + +- override def toString(): String = { +- name + " " + +- is_input + " " + +- ctype + " " + +- cwidth + " " + +- data + " " + +- ready + " " + +- valid +- } ++ override def toString(): String = { ++ name + " " + ++ is_input + " " + ++ ctype + " " + ++ cwidth + " " + ++ data + " " + ++ ready + " " + ++ valid ++ } + } + + class ComponentDef(a_type: String, a_name: String) { +diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala +index 17b8301..ce94c1a 100644 +--- a/src/main/scala/SysC.scala ++++ b/src/main/scala/SysC.scala +@@ -48,8 +48,11 @@ class SysCBackend extends CppBackend { + delt.bits match { + case bits: Bits => { + val is_input = bits.dir == INPUT +- val vtype = "dat_t<" + bits.width + ">" // direct use of width here? +- val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, delt.ready.name, delt.valid.name) ++ val vtype = "sc_uint<" + bits.width + ">"; var tcast = "" ++ if (is_input) { tcast = ".to_uint64()" } ++ else { tcast = ".to_ulong()" } ++ val vcast = tcast ++ val entry = new CEntry(name, is_input, vtype, vcast, bits.width, bits.name, delt.ready.name, delt.valid.name) + cdef.entries += (entry) + cdef.valid_ready = true + } +@@ -57,35 +60,67 @@ class SysCBackend extends CppBackend { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) + if (inputs.length > 0) { +- for (in <- inputs) { +- val vtype = "dat_t<" + in._2.width + ">" +- val entry = new CEntry(name, true, vtype, in._2.width, in._2.name, "ready", "valid") ++ for (in <- inputs) { ++ var ttype = ""; var tcast = "" ++ in._2 match { ++ case inUBool: Bool => ttype = "bool"; tcast = "" ++ case inSInt: SInt => ttype = "sc_int<" + in._2.width + ">"; tcast = ".to_uint64()" ++ //Bits is implemented as UInt ++ case inUInt: UInt => ttype = "sc_uint<" + in._2.width + ">"; tcast = ".to_uint64()" ++ } ++ val vtype = ttype; val vcast = tcast ++ val entry = new CEntry(name, true, vtype, vcast, in._2.width, in._2.name, "ready", "valid") + cdef.entries += (entry) + } +- //val aName = "cs_" + aggregate.name + "_i" +- //cdef.structs(aName)= new CStruct(aName, inputs) +- //val entry = new CEntry(name, true, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) + } + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { +- for (out <- outputs) { +- val vtype = "dat_t<" + out._2.width + ">" +- val entry = new CEntry(name, false, vtype, out._2.width, out._2.name, "ready", "valid") ++ for (out <- outputs) { ++ var ttype = ""; var tcast = "" ++ out._2 match { ++ case outUBool: Bool => ttype = "bool"; tcast = ".to_ulong()" ++ case outSInt: SInt => ttype = "sc_int<" + out._2.width + ">"; tcast = ".to_ulong()" ++ //Bits is implemented as UInt ++ case outUInt: UInt => ttype = "sc_uint<" + out._2.width + ">"; tcast = ".to_ulong()" ++ } ++ val vtype = ttype; val vcast = tcast ++ val entry = new CEntry(name, false, vtype, vcast, out._2.width, out._2.name, "ready", "valid") + cdef.entries += (entry) + } +- //val aName = "cs_" + aggregate.name + "_o" +- //cdef.structs(aName) = new CStruct(aName, outputs) +- //val entry = new CEntry(name, false, aName, 1, aggregate.name, delt.ready.name, delt.valid.name) + } + cdef.valid_ready = true + } + case _ => badElements(name) = elt + } + } +- case bits: Bits => { +- val is_input = bits.dir == INPUT +- val vtype = "dat_t<" + bits.width + ">" // direct use of width here? +- val entry = new CEntry(name, is_input, vtype, bits.width, bits.name, "ready", "valid") ++ case bool: Bool => { ++ val is_input = bool.dir == INPUT ++ val vtype = "bool"; var tcast = "" ++ if (is_input) { tcast = "" } ++ else { tcast = ".to_ulong()" } ++ val vcast = tcast ++ val entry = new CEntry(name, is_input, vtype, vcast, bool.width, bool.name, "ready", "valid") ++ cdef.entries += (entry) ++ cdef.valid_ready = false ++ } ++ case sint: SInt => { ++ val is_input = sint.dir == INPUT ++ val vtype = "sc_int<" + sint.width + ">"; var tcast = "" ++ if (is_input) { tcast = ".to_uint64()" } ++ else { tcast = ".to_ulong()" } ++ val vcast = tcast ++ val entry = new CEntry(name, is_input, vtype, vcast, sint.width, sint.name, "ready", "valid") ++ cdef.entries += (entry) ++ cdef.valid_ready = false ++ } ++ //Bits is implemented as UInt ++ case uint: UInt => { ++ val is_input = uint.dir == INPUT ++ val vtype = "sc_uint<" + uint.width + ">"; var tcast = "" ++ if (is_input) { tcast = ".to_uint64()" } ++ else { tcast = ".to_ulong()" } ++ val vcast = tcast ++ val entry = new CEntry(name, is_input, vtype, vcast, uint.width, uint.name, "ready", "valid") + cdef.entries += (entry) + cdef.valid_ready = false + } +-- +2.1.0 + diff --git a/patches/20150902/0007-Updated-SCWrapper.scala.-Cheked-Chisel-generation-fo.patch b/patches/20150902/0007-Updated-SCWrapper.scala.-Cheked-Chisel-generation-fo.patch new file mode 100644 index 00000000..3389b851 --- /dev/null +++ b/patches/20150902/0007-Updated-SCWrapper.scala.-Cheked-Chisel-generation-fo.patch @@ -0,0 +1,28 @@ +From 6097f4bf7e38d2d79a4e7747fa6fd99e585ef046 Mon Sep 17 00:00:00 2001 +From: Carlos Alberto Petry +Date: Wed, 2 Sep 2015 10:12:32 -0300 +Subject: [PATCH 7/7] Updated SCWrapper.scala. Cheked Chisel generation for + Decoupled and non-Decoupled signals -> all works fine. + +--- + src/main/scala/SCWrapper.scala | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala +index e5d2993..8b11632 100644 +--- a/src/main/scala/SCWrapper.scala ++++ b/src/main/scala/SCWrapper.scala +@@ -134,8 +134,8 @@ object SCWrapper { + if (c.valid_ready == true){ + sctor_list += ", %s__io_in_ready(\"%s__io_in_ready\")\n ".format(c.name, c.name) + sctor_list += ", %s__io_out_valid(\"%s__io_out_valid\")".format(c.name, c.name) +- output_ports += "sc_out > %s__io_in_ready;\n ".format(c.name) +- output_ports += "sc_out > %s__io_out_valid;\n ".format(c.name) ++ output_ports += "sc_out %s__io_in_ready;\n ".format(c.name) ++ output_ports += "sc_out %s__io_out_valid;\n ".format(c.name) + input_thread += "c->%s__io_in_valid = set;\n ".format(c.name) + input_thread += "c->%s__io_out_ready = set;\n ".format(c.name) + output_thread += "%s__io_out_valid->write(c->%s__io_out_valid.to_ulong());\n ".format(c.name, c.name) +-- +2.1.0 + diff --git a/patches/20150902/chisel_systemc_backend_patch.tar.gz b/patches/20150902/chisel_systemc_backend_patch.tar.gz new file mode 100644 index 00000000..95fb0cd7 Binary files /dev/null and b/patches/20150902/chisel_systemc_backend_patch.tar.gz differ diff --git a/src/main/resources/template_cpp.txt b/src/main/resources/template_cpp.txt new file mode 100644 index 00000000..28838341 --- /dev/null +++ b/src/main/resources/template_cpp.txt @@ -0,0 +1,17 @@ +#include "{!name!}.h" + +void {!name!}::component_thread(void){ + while(true){ + {!input_thread!} + //Clock Lo + c->clock_lo(reset); + + //Clock Hi + c->clock_hi(reset); + + {!output_thread!} + + wait(Step); + } +} + diff --git a/src/main/resources/template_h.txt b/src/main/resources/template_h.txt new file mode 100644 index 00000000..b90b9281 --- /dev/null +++ b/src/main/resources/template_h.txt @@ -0,0 +1,52 @@ +#ifndef __{!name!}__ +#define __{!name!}__ + +#include +#include "{!header_file!}" + +// ======================================== +// dat_t needs to have this operator defined, so that +// I'm allowed to use it with System C. +// But be warned: I don't quite know what I +// am doing. +// ======================================== +template +inline ostream& operator << (ostream& os, const dat_t& arg){ + return os; +} + +SC_MODULE({!name!}){ + {!component_type!}* c; + + // in ports + {!input_ports!} + // out ports + {!output_ports!} + SC_HAS_PROCESS({!name!}); + {!name!}(sc_module_name a_name, sc_time _step) + : sc_module(a_name), Step(_step) + {!sctor_list!} + { + // Initialize Component, Clock in RESET + c = new {!component_type!}(); + c->init(); + Step = Step; + + // Clock Initialization? Don't understand what this is for. Copied from emulator. + for(int i = 0; i < 5; i++) { + c->clock_lo(reset); + c->clock_hi(reset); + } + + //Register Thread + SC_THREAD(component_thread); + } + + void component_thread(void); + + dat_t<1> reset = LIT<1>(0); + dat_t<1> set = LIT<1>(1); + sc_time Step; +}; + +#endif //__{!name!}__ diff --git a/src/main/scala/SCWrapper.scala b/src/main/scala/SCWrapper.scala index d1d659db..35569977 100644 --- a/src/main/scala/SCWrapper.scala +++ b/src/main/scala/SCWrapper.scala @@ -54,21 +54,21 @@ object SCWrapper { def example_component_def(): ComponentDef = { val cdef = new ComponentDef("GCD_t", "GCD") - cdef.entries += new CEntry("a", true, "dat_t<1>", "GCD__io_a", "GCD__io_r1", "GCD__io_v1") - cdef.entries += new CEntry("z", false, "dat_t<1>", "GCD__io_z", "GCD__io_rz", "GCD__io_vz") + cdef.entries += new CEntry("a", true, "dat_t<1>", "dat_t<1>", 1, "GCD__io_a") + cdef.entries += new CEntry("z", false, "dat_t<1>", "dat_t<1>", 1, "GCD__io_z") cdef } def example_component_def2(): ComponentDef = { val cdef = new ComponentDef("AddFilter_t", "AddFilter") - cdef.entries += new CEntry("a", true, "dat_t<16>", "AddFilter__io_a", "AddFilter__io_ar", "AddFilter__io_av") - cdef.entries += new CEntry("b", false, "dat_t<16>", "AddFilter__io_b", "AddFilter__io_br", "AddFilter__io_bv") + cdef.entries += new CEntry("a", true, "dat_t<16>", "dat_t<1>", 16, "AddFilter__io_a") + cdef.entries += new CEntry("b", false, "dat_t<16>", "dat_t<1>", 16, "AddFilter__io_b") cdef } - def genwrapper(c: ComponentDef, filename: String) { + def genwrapper(c: ComponentDef, filename: String, templatefile: String) { //Read in template - val template = read_resource("template.txt") + val template = read_resource(templatefile) //Generate replacements val replacements = generate_replacements(c) @@ -81,9 +81,9 @@ object SCWrapper { System.out.println(filled) } - def genwrapper(c: ComponentDef, filewriter: java.io.FileWriter){ + def genwrapper(c: ComponentDef, filewriter: java.io.FileWriter, templatefile: String){ //Read in template - val template = read_resource("template.txt") + val template = read_resource(templatefile) //Generate replacements val replacements = generate_replacements(c) @@ -106,62 +106,106 @@ object SCWrapper { replacements += (("name", "SCWrapped" + c.name)) replacements += (("component_type", c.ctype)) - //I/O Fifos + //I/O Ports /*begin*/{ - var input_fifos = "" - var output_fifos = "" + var input_ports = "" + var output_ports = "" + var sctor_list = "" + var input_thread = "" + var output_thread = "" + var fname = "" + for( e <- c.entries) { - val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) + val decl_in = "sc_in<%s > %s;\n ".format(e.ctype, e.data) + val decl_out = "sc_out<%s > %s;\n ".format(e.ctype, e.data) + val thread_in = "c->%s = LIT<%s>(%s->read()%s);\n ".format(e.data, e.cwidth, e.data, e.ccast) + val thread_out = "%s->write(c->%s%s);\n ".format(e.data, e.data, e.ccast) + //val decl = "sc_fifo<%s >* %s;\n ".format(e.ctype, e.name) if(e.is_input) { - input_fifos += decl + input_ports += decl_in + sctor_list += ", %s(\"%s\")\n ".format(e.data, e.data) + //sensitive_list += " << %s__io_%s".format(c.name, e.name) + input_thread += thread_in } else { - output_fifos += decl + output_ports += decl_out + sctor_list += ", %s(\"%s\")\n ".format(e.data, e.data) + output_thread += thread_out } + // Generate ready and valid signals when necessary +/* if (e.name != fname){ + fname = e.name + if (e.valid != ""){ + sctor_list += ", %s(\"%s\")\n ".format(e.valid, e.valid) + if(e.is_input){ + input_ports += "sc_in %s;\n ".format(e.valid) + input_thread += "c->%s = LIT<1>(%s->read());\n ".format(e.valid, e.valid) + }else{ + output_ports += "sc_out %s;\n ".format(e.valid) + output_thread += "%s->write(c->%s.to_ulong());\n ".format(e.valid, e.valid) + } + if (e.ready != ""){ + sctor_list += ", %s(\"%s\")\n ".format(e.ready, e.ready) + if(e.is_input){ + input_ports += "sc_in %s;\n ".format(e.ready) + input_thread += "c->%s = LIT<1>(%s->read());\n ".format(e.ready, e.ready) + }else{ + output_ports += "sc_out %s;\n ".format(e.ready) + output_thread += "%s->write(c->%s.to_ulong());\n ".format(e.ready, e.ready) + } + } + } + } */ } - replacements += (("input_fifos", input_fifos)) - replacements += (("output_fifos", output_fifos)) + + replacements += (("input_ports", input_ports)) + replacements += (("output_ports", output_ports)) + replacements += (("sctor_list", sctor_list)) + //sensitive_list += ";" + //replacements += (("sensitive_list", sensitive_list)) + replacements += (("input_thread", input_thread)) + replacements += (("output_thread", output_thread)) } - /*Initialize output fifos*/{ - //Pull out output fifos - val fifos = ArrayBuffer[CEntry](); + /*Initialize output ports*/{ + //Pull out output ports + val ports = ArrayBuffer[CEntry](); for(e <- c.entries) { if(!e.is_input) { - fifos += e; + ports += e; } } //Initialize var init = ""; - for( i <- 0 until fifos.size) { - init += "%s = new sc_fifo<%s >(1);\n ".format(fifos(i).name, fifos(i).ctype) + for( i <- 0 until ports.size) { + init += "%s = new sc_fifo**???**<%s >(1);\n ".format(ports(i).name, ports(i).ctype) } replacements += (("init_output_fifos", init)) } /*Check input queues*/{ - //Pull out input fifos + //Pull out input ports val dvar = ArrayBuffer[String]() val fvar = ArrayBuffer[String]() - val fifos = ArrayBuffer[CEntry]() + val ports = ArrayBuffer[CEntry]() for( e <- c.entries) { if(e.is_input) { dvar += genvar("dat") fvar += genvar("filled") - fifos += e + ports += e } } //Initialize var init = "" var fill = "" var check = "" - for( i <- 0 until fifos.size) { - val ctype = fifos(i).ctype + for( i <- 0 until ports.size) { + val ctype = ports(i).ctype val data = dvar(i) val filled = fvar(i) - val in = fifos(i).name - val in_data = fifos(i).data - val ready = fifos(i).ready - val valid = fifos(i).valid + val in = ports(i).name + val in_data = ports(i).data + val ready = "ready" //ports(i).ready + val valid = "valid" //ports(i).valid init += "%s %s;\n ".format(ctype, data) init += "int %s = 0;\n ".format(filled) fill += "if(!%s){%s = %s->nb_read(%s);}\n "format(filled, filled, in, data) @@ -183,22 +227,22 @@ object SCWrapper { } /*Check Output Queues*/{ - //Pull out output fifos - val fifos = ArrayBuffer[CEntry]() - for (e <- c.entries) { - if(!e.is_input) { - fifos += e - } - } + //Pull out output ports + val ports = ArrayBuffer[CEntry]() + for (e <- c.entries) { + if(!e.is_input) { + ports += e + } + } //Check var check = "" var valid_output = ""; - for(i <- 0 until fifos.size) { - val ctype = fifos(i).ctype - val valid = fifos(i).valid - val data = fifos(i).data - val ready = fifos(i).ready - val out = fifos(i).name + for(i <- 0 until ports.size) { + val ctype = ports(i).ctype + val valid = "valid" //ports(i).valid + val data = ports(i).data + val ready = "ready" //ports(i).ready + val out = ports(i).name check += "c->%s = LIT<1>(%s->num_free() > 0);\n "format(ready, out) // Is this a structured data-type? if (ctype == data) { @@ -220,11 +264,11 @@ object SCWrapper { // If we have structured FIFO elements, we need to generate the struct definitions // and the ostream "<<" definition to keep SystemC happy. - val ostream_lsh = ArrayBuffer[String]() +/* val ostream_lsh = ArrayBuffer[String]() for((name, struct) <- c.structs) { ostream_lsh += struct.toString + "inline ostream& operator << (ostream& os, const %s& arg){ return os; }\n".format(name) } - replacements += (("ostream_lsh", ostream_lsh.mkString("\n"))) + replacements += (("ostream_lsh", ostream_lsh.mkString("\n"))) */ replacements } @@ -309,22 +353,22 @@ object SCWrapper { } } -class CEntry(a_name: String, input: Boolean, a_type: String, a_data: String, a_ready: String, a_valid: String) { - val name = a_name - val is_input = input - val ctype = a_type - val data = a_data - val ready = a_ready - val valid = a_valid +class CEntry(a_name: String, input: Boolean, a_type: String, a_cast: String, a_width: Int, a_data: String) { + val name = a_name + val is_input = input + val ctype = a_type + val ccast = a_cast + val cwidth = a_width + val data = a_data - override def toString(): String = { - name + " " + - is_input + " " + - ctype + " " + - data + " " + - ready + " " + - valid - } + override def toString(): String = { + name + " " + + is_input + " " + + ctype + " " + + ccast + " " + + cwidth + " " + + data + } } class ComponentDef(a_type: String, a_name: String) { diff --git a/src/main/scala/SysC.scala b/src/main/scala/SysC.scala index 566a3cfa..195ec533 100644 --- a/src/main/scala/SysC.scala +++ b/src/main/scala/SysC.scala @@ -30,48 +30,288 @@ package Chisel -/** If we have structured/aggregate types as top-level ports, we define suitable structures - * for encapsulating their components, in order to treat them as sc_fifo elements. - */ class SysCBackend extends CppBackend { - override def elaborate(c: Module): Unit = { + def bool_fun (name: String, bool: Bool): CEntry = { + val is_input = bool.dir == INPUT + val vtype = "bool"; var tcast = "" + if (is_input) { tcast = "" } + else { tcast = ".to_ulong()" } + val vcast = tcast + val entry = new CEntry(name, is_input, vtype, vcast, bool.width, bool.name) + entry + } + + def sint_fun (name: String, sint: SInt): CEntry = { + val is_input = sint.dir == INPUT + val vtype = "sc_int<" + sint.width + ">"; var tcast = "" + if (is_input) { tcast = ".to_uint64()" } + else { tcast = ".to_ulong()" } + val vcast = tcast + val entry = new CEntry(name, is_input, vtype, vcast, sint.width, sint.name) + entry + } + + // UInt: Bits is a virtual UInt class + def uint_fun (name: String, uint: UInt): CEntry = { + val is_input = uint.dir == INPUT + val vtype = "sc_uint<" + uint.width + ">"; var tcast = "" + if (is_input) { tcast = ".to_uint64()" } + else { tcast = ".to_ulong()" } + val vcast = tcast + val entry = new CEntry(name, is_input, vtype, vcast, uint.width, uint.name) + entry + } + + // Used for Decoupled and Valid types + def bits_fun (name: String, bits: Bits): CEntry = { + val is_input = bits.dir == INPUT + val vtype = "sc_uint<" + bits.width + ">"; var tcast = "" + if (is_input) { tcast = ".to_uint64()" } + else { tcast = ".to_ulong()" } + val vcast = tcast + val entry = new CEntry(name, is_input, vtype, vcast, bits.width, bits.name) + entry + } + + def valid_fun (velt: ValidIO[_], cdef: ComponentDef, name: String): Boolean = { + var velt_bad = false + // Generate Valid signal + val ventry = bool_fun(velt.valid.name, velt.valid) + cdef.entries += (ventry) + velt.bits match { + case bits: Bits => { + val entry = bits_fun(name, bits) + cdef.entries += (entry) + } + case aggregate: Aggregate => { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) + if (inputs.length > 0) { + for (in <- inputs) { + in._2 match { + case inBool: Bool => { + val entry = bool_fun(name, inBool) + cdef.entries += (entry) + } + case inSInt: SInt => { + val entry = sint_fun(name, inSInt) + cdef.entries += (entry) + } + //Also used for Bits + case inUInt: UInt => { + val entry = uint_fun(name, inUInt) + cdef.entries += (entry) + } + } + } + } + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { + for (out <- outputs) { + out._2 match { + case outBool: Bool => { + val entry = bool_fun(name, outBool) + cdef.entries += (entry) + } + case outSInt: SInt => { + val entry = sint_fun(name, outSInt) + cdef.entries += (entry) + } + //Also used for Bits + case outUInt: UInt => { + val entry = uint_fun(name, outUInt) + cdef.entries += (entry) + } + } + } + } + } + case _ => velt_bad = true + } + velt_bad + } + + def decoupled_fun (delt: DecoupledIO[_], cdef: ComponentDef, name: String): Boolean = { + var delt_bad = false + // Generate Ready and Valid signals + val rentry = bool_fun(delt.ready.name, delt.ready) + cdef.entries += (rentry) + val ventry = bool_fun(delt.valid.name, delt.valid) + cdef.entries += (ventry) + + delt.bits match { + case bits: Bits => { + val entry = bits_fun(name, bits) + cdef.entries += (entry) + } + case aggregate: Aggregate => { + // Collect all the inputs and outputs. + val inputs = aggregate.flatten.filter(_._2.dir == INPUT) + if (inputs.length > 0) { + for (in <- inputs) { + in._2 match { + case inBool: Bool => { + val entry = bool_fun(name, inBool) + cdef.entries += (entry) + } + case inSInt: SInt => { + val entry = sint_fun(name, inSInt) + cdef.entries += (entry) + } + //Also used for Bits + case inUInt: UInt => { + val entry = uint_fun(name, inUInt) + cdef.entries += (entry) + } + } + } + } + val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) + if (outputs.length > 0) { + for (out <- outputs) { + out._2 match { + case outBool: Bool => { + val entry = bool_fun(name, outBool) + cdef.entries += (entry) + } + case outSInt: SInt => { + val entry = sint_fun(name, outSInt) + cdef.entries += (entry) + } + //Also used for Bits + case outUInt: UInt => { + val entry = uint_fun(name, outUInt) + cdef.entries += (entry) + } + } + } + } + } + case _ => delt_bad = true + } + delt_bad + } +//================================================================================== + override def elaborate(c: Module): Unit = { super.elaborate(c) println(c) println(c.name) - //Create component definition for System C + //Create component definition for System C val top_bundle = c.io.asInstanceOf[Bundle] //Is this safe? // No, but it will throw an exception that should explain the issue reasonably val cdef = new ComponentDef(c.name + "_t", c.name) val badElements = scala.collection.mutable.HashMap[String, Data]() for ((name, elt) <- top_bundle.elements) { elt match { + case bool: Bool => { + val entry = bool_fun(name, bool) + cdef.entries += (entry) + } + + case sint: SInt => { + val entry = sint_fun(name, sint) + cdef.entries += (entry) + } + + // UInt & Bits + case uint: UInt => { + val entry = uint_fun(name, uint) + cdef.entries += (entry) + } + + case velt:ValidIO[_] => { + val velt_bad = valid_fun(velt, cdef, name) + if (velt_bad) badElements(name) = velt + } + case delt:DecoupledIO[_] => { - delt.bits match { - case bits: Bits => { - val is_input = bits.dir == INPUT - val vtype = "dat_t<" + bits.width + ">" // direct use of width here? - val entry = new CEntry(name, is_input, vtype, bits.name, delt.ready.name, delt.valid.name) - cdef.entries += (entry) + val delt_bad = decoupled_fun(delt, cdef, name) + if (delt_bad) badElements(name) = delt + } + + case belt: Bundle => { + val belt_bundle = belt.asInstanceOf[Bundle] + for ((hname, helt) <- belt_bundle.elements){ + helt match{ + case bbool: Bool => { + val entry = bool_fun(hname, bbool) + cdef.entries += (entry) + } + case bsint: SInt => { + val entry = sint_fun(hname, bsint) + cdef.entries += (entry) + } + // UInt & Bits + case buint: UInt => { + val entry = uint_fun(hname, buint) + cdef.entries += (entry) + } + case bvelt:ValidIO[_] => { + val bvelt_bad = valid_fun(bvelt, cdef, name) + if (bvelt_bad) badElements(name) = bvelt + } + case bdelt:DecoupledIO[_] => { + val bdelt_bad = decoupled_fun(bdelt, cdef, name) + if (bdelt_bad) badElements(name) = bdelt + } + case _ => badElements(hname) = helt + } + } + } + + case vecelt: Vec[_] => { + val inputs = vecelt.flatten.filter(_._2.dir == INPUT) + for (in <- inputs) { + in._2 match { + case inBool: Bool => { + val entry = bool_fun(name, inBool) + cdef.entries += (entry) + } + case inSInt: SInt => { + val entry = sint_fun(name, inSInt) + cdef.entries += (entry) + } + //Also used for Bits + case inUInt: UInt => { + val entry = uint_fun(name, inUInt) + cdef.entries += (entry) + } + case vecvelt:ValidIO[_] => { + val vecvelt_bad = valid_fun(vecvelt, cdef, name) + if (vecvelt_bad) badElements(name) = vecvelt + } + case vecdelt:DecoupledIO[_] => { + val vecdelt_bad = decoupled_fun(vecdelt, cdef, name) + if (vecdelt_bad) badElements(name) = vecdelt + } } - case aggregate: Aggregate => { - // Collect all the inputs and outputs. - val inputs = aggregate.flatten.filter(_._2.dir == INPUT) - if (inputs.length > 0) { - val aName = "cs_" + aggregate.name + "_i" - cdef.structs(aName)= new CStruct(aName, inputs) - val entry = new CEntry(name, true, aName, aName, delt.ready.name, delt.valid.name) + } + val outputs = vecelt.flatten.filter(_._2.dir == OUTPUT) + for (out <- outputs) { + out._2 match { + case outBool: Bool => { + val entry = bool_fun(name, outBool) + cdef.entries += (entry) + } + case outSInt: SInt => { + val entry = sint_fun(name, outSInt) cdef.entries += (entry) } - val outputs = aggregate.flatten.filter(_._2.dir == OUTPUT) - if (outputs.length > 0) { - val aName = "cs_" + aggregate.name + "_o" - cdef.structs(aName) = new CStruct(aName, outputs) - val entry = new CEntry(name, false, aName, aName, delt.ready.name, delt.valid.name) + //Also used for Bits + case outUInt: UInt => { + val entry = uint_fun(name, outUInt) cdef.entries += (entry) } + case vecvelt:ValidIO[_] => { + val vecvelt_bad = valid_fun(vecvelt, cdef, name) + if (vecvelt_bad) badElements(name) = vecvelt + } + case vecdelt:DecoupledIO[_] => { + val vecdelt_bad = decoupled_fun(vecdelt, cdef, name) + if (vecdelt_bad) badElements(name) = vecdelt + } } - case _ => badElements(name) = elt } } case _ => badElements(name) = elt @@ -93,9 +333,13 @@ class SysCBackend extends CppBackend { //Print out the component definition. println(cdef) - //Generate the file. - val out_p = createOutputFile("SCWrapped" + c.name + ".cpp"); - SCWrapper.genwrapper(cdef, out_p) + //Generate SCWrapped files + val out_h = createOutputFile("SCWrapped" + c.name + ".h"); + val template_h = "template_h.txt" + SCWrapper.genwrapper(cdef, out_h, template_h) + val out_cpp = createOutputFile("SCWrapped" + c.name + ".cpp"); + val template_cpp = "template_cpp.txt" + SCWrapper.genwrapper(cdef, out_cpp, template_cpp) } } } diff --git a/src/test/scala/SysCTest/FullAdder.scala b/src/test/scala/SysCTest/FullAdder.scala index 28d73f2b..1e14a314 100644 --- a/src/test/scala/SysCTest/FullAdder.scala +++ b/src/test/scala/SysCTest/FullAdder.scala @@ -63,9 +63,6 @@ class FullAdderTests(c: FullAdder) extends Tester(c) { val a = rnd.nextInt(2) val b = rnd.nextInt(2) val cin = rnd.nextInt(2) - val res = a + b + cin - val sum = res & 1 - val cout = (res >> 1) & 1 var transfer = false poke(c.io.in.valid, 0) poke(c.io.out.ready, 0) @@ -81,6 +78,10 @@ class FullAdderTests(c: FullAdder) extends Tester(c) { poke(c.io.in.valid, 1) poke(c.io.out.ready, 1) + val res = a + b + cin + val sum = res & 1 + val cout = (res >> 1) & 1 + do { transfer = (peek(c.io.out.valid) == 1) step(1)