aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml10
-rw-r--r--README.md3
-rw-r--r--backends/firrtl/firrtl.cc3
-rw-r--r--examples/anlogic/.gitignore4
-rw-r--r--examples/anlogic/README13
-rwxr-xr-xexamples/anlogic/build.sh4
-rw-r--r--examples/anlogic/build.tcl11
-rw-r--r--examples/anlogic/demo.adc2
-rw-r--r--examples/anlogic/demo.v18
-rw-r--r--examples/anlogic/demo.ys3
-rw-r--r--examples/igloo2/libero.tcl14
-rw-r--r--examples/igloo2/runme.sh4
-rw-r--r--frontends/ast/ast.h3
-rw-r--r--frontends/ast/genrtlil.cc6
-rw-r--r--frontends/ast/simplify.cc67
-rw-r--r--passes/hierarchy/hierarchy.cc2
-rw-r--r--techlibs/xilinx/synth_xilinx.cc2
-rw-r--r--tests/simple/xfirrtl1
18 files changed, 153 insertions, 17 deletions
diff --git a/.travis.yml b/.travis.yml
index 8aacbb8b1..7c6e4e43c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -132,11 +132,11 @@ matrix:
env:
- MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0"
- # Latest clang on Mac OS X
- - os: osx
- osx_image: xcode9.4
- env:
- - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++"
+# # Latest clang on Mac OS X
+# - os: osx
+# osx_image: xcode9.4
+# env:
+# - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++"
before_install:
- ./.travis/setup.sh
diff --git a/README.md b/README.md
index f17046488..9bac468a7 100644
--- a/README.md
+++ b/README.md
@@ -309,6 +309,9 @@ Verilog Attributes and non-standard features
passes to identify input and output ports of cells. The Verilog backend
also does not output blackbox modules on default.
+- The ``dynports'' attribute is used by the Verilog front-end to mark modules
+ that have ports with a width that depends on a parameter.
+
- The ``keep`` attribute on cells and wires is used to mark objects that should
never be removed by the optimizer. This is used for example for cells that
have hidden connections that are not part of the netlist, such as IO pads.
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 88c1038b7..eef6401b2 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -165,8 +165,7 @@ struct FirrtlWorker
std::string fid(RTLIL::IdString internal_id)
{
- const char *str = internal_id.c_str();
- return *str == '\\' ? str + 1 : str;
+ return make_id(internal_id);
}
std::string cellname(RTLIL::Cell *cell)
diff --git a/examples/anlogic/.gitignore b/examples/anlogic/.gitignore
new file mode 100644
index 000000000..fa9424cd8
--- /dev/null
+++ b/examples/anlogic/.gitignore
@@ -0,0 +1,4 @@
+demo.bit
+demo_phy.area
+full.v
+*.log \ No newline at end of file
diff --git a/examples/anlogic/README b/examples/anlogic/README
new file mode 100644
index 000000000..99143cce0
--- /dev/null
+++ b/examples/anlogic/README
@@ -0,0 +1,13 @@
+LED Blink project for Anlogic Lichee Tang board.
+
+Follow the install instructions for the Tang Dynasty IDE from given link below.
+
+https://tang.sipeed.com/en/getting-started/installing-td-ide/linux/
+
+
+set TD_HOME env variable to the full path to the TD <TD Install Directory> as follow.
+
+export TD_HOME=<TD Install Directory>
+
+then run "bash build.sh" in this directory.
+
diff --git a/examples/anlogic/build.sh b/examples/anlogic/build.sh
new file mode 100755
index 000000000..e0f6b4cfe
--- /dev/null
+++ b/examples/anlogic/build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -ex
+yosys demo.ys
+$TD_HOME/bin/td build.tcl
diff --git a/examples/anlogic/build.tcl b/examples/anlogic/build.tcl
new file mode 100644
index 000000000..db8c3b347
--- /dev/null
+++ b/examples/anlogic/build.tcl
@@ -0,0 +1,11 @@
+import_device eagle_s20.db -package BG256
+read_verilog full.v -top demo
+read_adc demo.adc
+optimize_rtl
+map_macro
+map
+pack
+place
+route
+report_area -io_info -file demo_phy.area
+bitgen -bit demo.bit -version 0X00 -g ucode:00000000000000000000000000000000
diff --git a/examples/anlogic/demo.adc b/examples/anlogic/demo.adc
new file mode 100644
index 000000000..c8fbaed3e
--- /dev/null
+++ b/examples/anlogic/demo.adc
@@ -0,0 +1,2 @@
+set_pin_assignment {CLK_IN} { LOCATION = K14; } ##24MHZ
+set_pin_assignment {R_LED} { LOCATION = R3; } ##R_LED \ No newline at end of file
diff --git a/examples/anlogic/demo.v b/examples/anlogic/demo.v
new file mode 100644
index 000000000..a7edf4e37
--- /dev/null
+++ b/examples/anlogic/demo.v
@@ -0,0 +1,18 @@
+module demo (
+ input wire CLK_IN,
+ output wire R_LED
+);
+ parameter time1 = 30'd12_000_000;
+ reg led_state;
+ reg [29:0] count;
+
+ always @(posedge CLK_IN)begin
+ if(count == time1)begin
+ count<= 30'd0;
+ led_state <= ~led_state;
+ end
+ else
+ count <= count + 1'b1;
+ end
+ assign R_LED = led_state;
+endmodule \ No newline at end of file
diff --git a/examples/anlogic/demo.ys b/examples/anlogic/demo.ys
new file mode 100644
index 000000000..5687bcd31
--- /dev/null
+++ b/examples/anlogic/demo.ys
@@ -0,0 +1,3 @@
+read_verilog demo.v
+synth_anlogic -top demo
+write_verilog full.v \ No newline at end of file
diff --git a/examples/igloo2/libero.tcl b/examples/igloo2/libero.tcl
index 1f3476316..6f7d4e24b 100644
--- a/examples/igloo2/libero.tcl
+++ b/examples/igloo2/libero.tcl
@@ -15,6 +15,7 @@ new_project \
import_files -hdl_source {netlist.vm}
import_files -sdc {example.sdc}
import_files -io_pdc {example.pdc}
+build_design_hierarchy
set_option -synth 0
organize_tool_files -tool PLACEROUTE \
@@ -32,22 +33,25 @@ configure_tool -name PLACEROUTE \
-params EFFORT_LEVEL:false \
-params REPAIR_MIN_DELAY:false
+puts ""
puts "**> COMPILE"
run_tool -name {COMPILE}
puts "<** COMPILE"
+puts ""
puts "**> PLACEROUTE"
run_tool -name {PLACEROUTE}
puts "<** PLACEROUTE"
+puts ""
puts "**> VERIFYTIMING"
run_tool -name {VERIFYTIMING}
puts "<** VERIFYTIMING"
-save_project
-
-# puts "**> export_bitstream"
-# export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC}
-# puts "<** export_bitstream"
+puts ""
+puts "**> BITSTREAM"
+export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC}
+puts "<** BITSTREAM"
+puts ""
exit 0
diff --git a/examples/igloo2/runme.sh b/examples/igloo2/runme.sh
index 54247759f..a08894e0a 100644
--- a/examples/igloo2/runme.sh
+++ b/examples/igloo2/runme.sh
@@ -1,4 +1,6 @@
#!/bin/bash
set -ex
yosys -p 'synth_sf2 -top example -edif netlist.edn -vlog netlist.vm' example.v
-LM_LICENSE_FILE=1702@`hostname` /opt/microsemi/Libero_SoC_v11.9/Libero/bin/libero SCRIPT:libero.tcl
+export LM_LICENSE_FILE=${LM_LICENSE_FILE:-1702@localhost}
+/opt/microsemi/Libero_SoC_v12.0/Libero/bin/libero SCRIPT:libero.tcl
+cp proj/designer/example/export/example.stp .
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 08f91c9c3..8b185ff51 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -214,6 +214,8 @@ namespace AST
MEM2REG_FL_SET_ASYNC = 0x00000800,
MEM2REG_FL_EQ2 = 0x00001000,
MEM2REG_FL_CMPLX_LHS = 0x00002000,
+ MEM2REG_FL_CONST_LHS = 0x00004000,
+ MEM2REG_FL_VAR_LHS = 0x00008000,
/* proc flags */
MEM2REG_FL_EQ1 = 0x01000000,
@@ -237,6 +239,7 @@ namespace AST
bool has_const_only_constructs(bool &recommend_const_eval);
void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
AstNode *eval_const_function(AstNode *fcall);
+ bool is_simple_const_expr();
// create a human-readable text representation of the AST (for debugging)
void dumpAst(FILE *f, std::string indent) const;
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 2d591b29d..13383845a 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -544,7 +544,11 @@ struct AST_INTERNAL::ProcessGenerator
break;
case AST_WIRE:
- log_file_error(ast->filename, ast->linenum, "Found wire declaration in block without label!\n");
+ log_file_error(ast->filename, ast->linenum, "Found reg declaration in block without label!\n");
+ break;
+
+ case AST_ASSIGN:
+ log_file_error(ast->filename, ast->linenum, "Found continous assignment in always/initial block!\n");
break;
case AST_PARAMETER:
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 46013544b..7160c6c0f 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -113,6 +113,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
goto verbose_activate;
+ if ((memflags & AstNode::MEM2REG_FL_CONST_LHS) && !(memflags & AstNode::MEM2REG_FL_VAR_LHS))
+ goto verbose_activate;
+
// log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
continue;
@@ -325,6 +328,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
if (node->type == AST_WIRE) {
+ if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
+ for (auto c : node->children[0]->children) {
+ if (!c->is_simple_const_expr()) {
+ if (attributes.count("\\dynports"))
+ delete attributes.at("\\dynports");
+ attributes["\\dynports"] = AstNode::mkconst_int(1, true);
+ }
+ }
+ }
if (this_wire_scope.count(node->str) > 0) {
AstNode *first_node = this_wire_scope[node->str];
if (first_node->is_input && node->is_reg)
@@ -938,7 +950,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
}
if (current_scope.count(str) == 0) {
- if (flag_autowire) {
+ if (flag_autowire || str == "\\$global_clock") {
AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
auto_wire->str = str;
current_ast_mod->children.push_back(auto_wire);
@@ -2169,6 +2181,8 @@ skip_dynamic_range_lvalue_expansion:;
}
newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr, unconditional_init);
+ delete node_filename;
+ delete node_memory;
goto apply_newNode;
}
@@ -2936,6 +2950,14 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
}
+ // remember if this is a constant index or not
+ if (children[0]->children.size() && children[0]->children[0]->type == AST_RANGE && children[0]->children[0]->children.size()) {
+ if (children[0]->children[0]->children[0]->type == AST_CONSTANT)
+ mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CONST_LHS;
+ else
+ mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_VAR_LHS;
+ }
+
// remember where this is
if (flags & MEM2REG_FL_INIT) {
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
@@ -3048,6 +3070,39 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
if (type == AST_FUNCTION || type == AST_TASK)
return false;
+ if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
+ {
+ log_assert(children[0]->type == AST_CONSTANT);
+ log_assert(children[1]->type == AST_CONSTANT);
+ log_assert(children[2]->type == AST_CONSTANT);
+
+ int cursor = children[0]->asInt(false);
+ Const data = children[1]->bitsAsConst();
+ int length = children[2]->asInt(false);
+
+ if (length != 0)
+ {
+ AstNode *block = new AstNode(AST_INITIAL, new AstNode(AST_BLOCK));
+ mod->children.push_back(block);
+ block = block->children[0];
+
+ int wordsz = GetSize(data) / length;
+
+ for (int i = 0; i < length; i++) {
+ block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false))), mkconst_bits(data.extract(i*wordsz, wordsz).bits, false)));
+ block->children.back()->children[0]->str = str;
+ block->children.back()->children[0]->id2ast = id2ast;
+ block->children.back()->children[0]->was_checked = true;
+ }
+ }
+
+ AstNode *newNode = new AstNode(AST_NONE);
+ newNode->cloneInto(this);
+ delete newNode;
+
+ did_something = true;
+ }
+
if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
{
if (async_block == NULL) {
@@ -3277,6 +3332,16 @@ bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
return false;
}
+bool AstNode::is_simple_const_expr()
+{
+ if (type == AST_IDENTIFIER)
+ return false;
+ for (auto child : children)
+ if (!child->is_simple_const_expr())
+ return false;
+ return true;
+}
+
// helper function for AstNode::eval_const_function()
void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
{
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 2d8edebb5..88c339e8c 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -910,7 +910,7 @@ struct HierarchyPass : public Pass {
if (m == nullptr)
continue;
- if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty()) {
+ if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 6c11d885d..3632f348f 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -252,7 +252,7 @@ struct SynthXilinxPass : public Pass
if (check_label(active, run_from, run_to, "edif"))
{
if (!edif_file.empty())
- Pass::call(design, stringf("write_edif %s", edif_file.c_str()));
+ Pass::call(design, stringf("write_edif -pvector bra %s", edif_file.c_str()));
}
if (check_label(active, run_from, run_to, "blif"))
{
diff --git a/tests/simple/xfirrtl b/tests/simple/xfirrtl
index 5bc75347b..50d693513 100644
--- a/tests/simple/xfirrtl
+++ b/tests/simple/xfirrtl
@@ -1,6 +1,7 @@
# This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures.
arraycells.v inst id[0] of
dff_different_styles.v
+dff_init.v Initial value not supported
generate.v combinational loop
hierdefparam.v inst id[0] of
i2c_master_tests.v $adff