mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
6d2ea6fe55
10
.travis.yml
10
.travis.yml
|
@ -132,11 +132,11 @@ matrix:
|
||||||
env:
|
env:
|
||||||
- MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0"
|
- MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0"
|
||||||
|
|
||||||
# Latest clang on Mac OS X
|
# # Latest clang on Mac OS X
|
||||||
- os: osx
|
# - os: osx
|
||||||
osx_image: xcode9.4
|
# osx_image: xcode9.4
|
||||||
env:
|
# env:
|
||||||
- MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++"
|
# - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- ./.travis/setup.sh
|
- ./.travis/setup.sh
|
||||||
|
|
22
README.md
22
README.md
|
@ -34,11 +34,24 @@ compatible license that is similar in terms to the MIT license
|
||||||
or the 2-clause BSD license).
|
or the 2-clause BSD license).
|
||||||
|
|
||||||
|
|
||||||
Web Site
|
Web Site and Other Resources
|
||||||
========
|
============================
|
||||||
|
|
||||||
More information and documentation can be found on the Yosys web site:
|
More information and documentation can be found on the Yosys web site:
|
||||||
http://www.clifford.at/yosys/
|
- http://www.clifford.at/yosys/
|
||||||
|
|
||||||
|
The "Documentation" page on the web site contains links to more resources,
|
||||||
|
including a manual that even describes some of the Yosys internals:
|
||||||
|
- http://www.clifford.at/yosys/documentation.html
|
||||||
|
|
||||||
|
The file `CodingReadme` in this directory contains additional information
|
||||||
|
for people interested in using the Yosys C++ APIs.
|
||||||
|
|
||||||
|
Users interested in formal verification might want to use the formal verification
|
||||||
|
front-end for Yosys, SymbiYosys:
|
||||||
|
- https://symbiyosys.readthedocs.io/en/latest/
|
||||||
|
- https://github.com/YosysHQ/SymbiYosys
|
||||||
|
|
||||||
|
|
||||||
Setup
|
Setup
|
||||||
======
|
======
|
||||||
|
@ -296,6 +309,9 @@ Verilog Attributes and non-standard features
|
||||||
passes to identify input and output ports of cells. The Verilog backend
|
passes to identify input and output ports of cells. The Verilog backend
|
||||||
also does not output blackbox modules on default.
|
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
|
- 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
|
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.
|
have hidden connections that are not part of the netlist, such as IO pads.
|
||||||
|
|
|
@ -130,7 +130,7 @@ struct EdifBackend : public Backend {
|
||||||
bool port_rename = false;
|
bool port_rename = false;
|
||||||
bool attr_properties = false;
|
bool attr_properties = false;
|
||||||
std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports;
|
std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports;
|
||||||
bool nogndvcc = false, gndvccy = true;
|
bool nogndvcc = false, gndvccy = false;
|
||||||
CellTypes ct(design);
|
CellTypes ct(design);
|
||||||
EdifNames edif_names;
|
EdifNames edif_names;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ new_project \
|
||||||
import_files -hdl_source {netlist.vm}
|
import_files -hdl_source {netlist.vm}
|
||||||
import_files -sdc {example.sdc}
|
import_files -sdc {example.sdc}
|
||||||
import_files -io_pdc {example.pdc}
|
import_files -io_pdc {example.pdc}
|
||||||
|
build_design_hierarchy
|
||||||
set_option -synth 0
|
set_option -synth 0
|
||||||
|
|
||||||
organize_tool_files -tool PLACEROUTE \
|
organize_tool_files -tool PLACEROUTE \
|
||||||
|
@ -32,22 +33,25 @@ configure_tool -name PLACEROUTE \
|
||||||
-params EFFORT_LEVEL:false \
|
-params EFFORT_LEVEL:false \
|
||||||
-params REPAIR_MIN_DELAY:false
|
-params REPAIR_MIN_DELAY:false
|
||||||
|
|
||||||
|
puts ""
|
||||||
puts "**> COMPILE"
|
puts "**> COMPILE"
|
||||||
run_tool -name {COMPILE}
|
run_tool -name {COMPILE}
|
||||||
puts "<** COMPILE"
|
puts "<** COMPILE"
|
||||||
|
|
||||||
|
puts ""
|
||||||
puts "**> PLACEROUTE"
|
puts "**> PLACEROUTE"
|
||||||
run_tool -name {PLACEROUTE}
|
run_tool -name {PLACEROUTE}
|
||||||
puts "<** PLACEROUTE"
|
puts "<** PLACEROUTE"
|
||||||
|
|
||||||
|
puts ""
|
||||||
puts "**> VERIFYTIMING"
|
puts "**> VERIFYTIMING"
|
||||||
run_tool -name {VERIFYTIMING}
|
run_tool -name {VERIFYTIMING}
|
||||||
puts "<** VERIFYTIMING"
|
puts "<** VERIFYTIMING"
|
||||||
|
|
||||||
save_project
|
puts ""
|
||||||
|
puts "**> BITSTREAM"
|
||||||
# puts "**> export_bitstream"
|
export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC}
|
||||||
# export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC}
|
puts "<** BITSTREAM"
|
||||||
# puts "<** export_bitstream"
|
|
||||||
|
|
||||||
|
puts ""
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -ex
|
set -ex
|
||||||
yosys -p 'synth_sf2 -top example -edif netlist.edn -vlog netlist.vm' example.v
|
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 .
|
||||||
|
|
|
@ -214,6 +214,8 @@ namespace AST
|
||||||
MEM2REG_FL_SET_ASYNC = 0x00000800,
|
MEM2REG_FL_SET_ASYNC = 0x00000800,
|
||||||
MEM2REG_FL_EQ2 = 0x00001000,
|
MEM2REG_FL_EQ2 = 0x00001000,
|
||||||
MEM2REG_FL_CMPLX_LHS = 0x00002000,
|
MEM2REG_FL_CMPLX_LHS = 0x00002000,
|
||||||
|
MEM2REG_FL_CONST_LHS = 0x00004000,
|
||||||
|
MEM2REG_FL_VAR_LHS = 0x00008000,
|
||||||
|
|
||||||
/* proc flags */
|
/* proc flags */
|
||||||
MEM2REG_FL_EQ1 = 0x01000000,
|
MEM2REG_FL_EQ1 = 0x01000000,
|
||||||
|
@ -237,6 +239,7 @@ namespace AST
|
||||||
bool has_const_only_constructs(bool &recommend_const_eval);
|
bool has_const_only_constructs(bool &recommend_const_eval);
|
||||||
void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
|
void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
|
||||||
AstNode *eval_const_function(AstNode *fcall);
|
AstNode *eval_const_function(AstNode *fcall);
|
||||||
|
bool is_simple_const_expr();
|
||||||
|
|
||||||
// create a human-readable text representation of the AST (for debugging)
|
// create a human-readable text representation of the AST (for debugging)
|
||||||
void dumpAst(FILE *f, std::string indent) const;
|
void dumpAst(FILE *f, std::string indent) const;
|
||||||
|
|
|
@ -544,7 +544,11 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_WIRE:
|
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;
|
break;
|
||||||
|
|
||||||
case AST_PARAMETER:
|
case AST_PARAMETER:
|
||||||
|
|
|
@ -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)
|
if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
|
||||||
goto verbose_activate;
|
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));
|
// log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
|
||||||
continue;
|
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++) {
|
for (size_t i = 0; i < children.size(); i++) {
|
||||||
AstNode *node = children[i];
|
AstNode *node = children[i];
|
||||||
if (node->type == AST_WIRE) {
|
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) {
|
if (this_wire_scope.count(node->str) > 0) {
|
||||||
AstNode *first_node = this_wire_scope[node->str];
|
AstNode *first_node = this_wire_scope[node->str];
|
||||||
if (first_node->is_input && node->is_reg)
|
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 (current_scope.count(str) == 0) {
|
||||||
if (flag_autowire) {
|
if (flag_autowire || str == "\\$global_clock") {
|
||||||
AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
|
AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
|
||||||
auto_wire->str = str;
|
auto_wire->str = str;
|
||||||
current_ast_mod->children.push_back(auto_wire);
|
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);
|
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;
|
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;
|
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
|
// remember where this is
|
||||||
if (flags & MEM2REG_FL_INIT) {
|
if (flags & MEM2REG_FL_INIT) {
|
||||||
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_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)
|
if (type == AST_FUNCTION || type == AST_TASK)
|
||||||
return false;
|
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 (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
|
||||||
{
|
{
|
||||||
if (async_block == NULL) {
|
if (async_block == NULL) {
|
||||||
|
@ -3277,6 +3332,16 @@ bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
|
||||||
return false;
|
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()
|
// helper function for AstNode::eval_const_function()
|
||||||
void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
|
void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
|
||||||
{
|
{
|
||||||
|
|
|
@ -910,7 +910,7 @@ struct HierarchyPass : public Pass {
|
||||||
if (m == nullptr)
|
if (m == nullptr)
|
||||||
continue;
|
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);
|
IdString new_m_name = m->derive(design, cell->parameters, true);
|
||||||
if (new_m_name.empty())
|
if (new_m_name.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -5,4 +5,4 @@ EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h
|
||||||
.SECONDARY: passes/pmgen/ice40_dsp_pm.h
|
.SECONDARY: passes/pmgen/ice40_dsp_pm.h
|
||||||
|
|
||||||
passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
|
passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
|
||||||
$(P) mkdir -p passes/pmgen && python3 $^
|
$(P) mkdir -p passes/pmgen && python3 $^ $@
|
||||||
|
|
|
@ -9,7 +9,8 @@ pp = pprint.PrettyPrinter(indent=4)
|
||||||
pmgfile = sys.argv[1]
|
pmgfile = sys.argv[1]
|
||||||
assert pmgfile.endswith(".pmg")
|
assert pmgfile.endswith(".pmg")
|
||||||
prefix = pmgfile[0:-4]
|
prefix = pmgfile[0:-4]
|
||||||
pmname = prefix.split('/')[-1]
|
prefix = prefix.split('/')[-1]
|
||||||
|
outfile = sys.argv[2]
|
||||||
|
|
||||||
state_types = dict()
|
state_types = dict()
|
||||||
udata_types = dict()
|
udata_types = dict()
|
||||||
|
@ -179,7 +180,7 @@ with open(pmgfile, "r") as f:
|
||||||
|
|
||||||
blocks.append(block)
|
blocks.append(block)
|
||||||
|
|
||||||
with open("%s_pm.h" % prefix, "w") as f:
|
with open(outfile, "w") as f:
|
||||||
print("// Generated by pmgen.py from {}.pgm".format(prefix), file=f)
|
print("// Generated by pmgen.py from {}.pgm".format(prefix), file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
|
@ -190,10 +191,10 @@ with open("%s_pm.h" % prefix, "w") as f:
|
||||||
print("YOSYS_NAMESPACE_BEGIN", file=f)
|
print("YOSYS_NAMESPACE_BEGIN", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
print("struct {}_pm {{".format(pmname), file=f)
|
print("struct {}_pm {{".format(prefix), file=f)
|
||||||
print(" Module *module;", file=f)
|
print(" Module *module;", file=f)
|
||||||
print(" SigMap sigmap;", file=f)
|
print(" SigMap sigmap;", file=f)
|
||||||
print(" std::function<void()> on_accept;".format(pmname), file=f)
|
print(" std::function<void()> on_accept;".format(prefix), file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
for index in range(len(blocks)):
|
for index in range(len(blocks)):
|
||||||
|
@ -291,7 +292,7 @@ with open("%s_pm.h" % prefix, "w") as f:
|
||||||
print(" }", file=f)
|
print(" }", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(pmname), file=f)
|
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f)
|
||||||
print(" module(module), sigmap(module) {", file=f)
|
print(" module(module), sigmap(module) {", file=f)
|
||||||
for s, t in sorted(udata_types.items()):
|
for s, t in sorted(udata_types.items()):
|
||||||
if t.endswith("*"):
|
if t.endswith("*"):
|
||||||
|
@ -321,7 +322,7 @@ with open("%s_pm.h" % prefix, "w") as f:
|
||||||
print(" }", file=f)
|
print(" }", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
print(" ~{}_pm() {{".format(pmname), file=f)
|
print(" ~{}_pm() {{".format(prefix), file=f)
|
||||||
print(" for (auto cell : autoremove_cells)", file=f)
|
print(" for (auto cell : autoremove_cells)", file=f)
|
||||||
print(" module->remove(cell);", file=f)
|
print(" module->remove(cell);", file=f)
|
||||||
print(" }", file=f)
|
print(" }", file=f)
|
||||||
|
@ -340,7 +341,7 @@ with open("%s_pm.h" % prefix, "w") as f:
|
||||||
print(" }", file=f)
|
print(" }", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
print(" void run(std::function<void({}_pm&)> on_accept_f) {{".format(pmname), file=f)
|
print(" void run(std::function<void({}_pm&)> on_accept_f) {{".format(prefix), file=f)
|
||||||
print(" run([&](){on_accept_f(*this);});", file=f)
|
print(" run([&](){on_accept_f(*this);});", file=f)
|
||||||
print(" }", file=f)
|
print(" }", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
|
@ -223,11 +223,12 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
|
||||||
|
|
||||||
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
|
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
|
||||||
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
|
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
|
||||||
|
wire srval;
|
||||||
generate
|
generate
|
||||||
if (LSRMODE == "PRLD")
|
if (LSRMODE == "PRLD")
|
||||||
wire srval = M;
|
assign srval = M;
|
||||||
else
|
else
|
||||||
localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0;
|
assign srval = (REGSET == "SET") ? 1'b1 : 1'b0;
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
initial Q = srval;
|
initial Q = srval;
|
||||||
|
|
Loading…
Reference in New Issue