From f1a2fd966f62df072d2c43573fb71a1369857523 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Mar 2013 11:51:12 +0200 Subject: [PATCH] Now only use value from "initial" when no matching "always" block is found --- frontends/ast/ast.cc | 16 +++++++++++++++- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 20 +++++++++++++++----- tests/k68_vltor/changes.diff | 13 ------------- tests/k68_vltor/run.sh | 2 +- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 391e0a444..cb0311b6b 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,6 +51,7 @@ namespace AST_INTERNAL { std::map current_scope; RTLIL::SigSpec *genRTLIL_subst_from = NULL; RTLIL::SigSpec *genRTLIL_subst_to = NULL; + RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; } @@ -704,6 +705,9 @@ static AstModule* process_module(AstNode *ast) current_module->ast = NULL; current_module->name = ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); + + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -718,10 +722,20 @@ static AstModule* process_module(AstNode *ast) } for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; - if (node->type != AST_WIRE && node->type != AST_MEMORY) + if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) node->genRTLIL(); } + ignoreThisSignalsInInitial.sort_and_unify(); + + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_INITIAL) + node->genRTLIL(); + } + + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; current_module->nomem2reg = flag_nomem2reg; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 918f12c1a..acf10f9ad 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -221,7 +221,7 @@ namespace AST_INTERNAL extern bool flag_dump_ast, flag_dump_ast_diff, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; - extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to; + extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; struct ProcessGenerator; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2f5370fe8..36074be34 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -183,7 +183,9 @@ struct AST_INTERNAL::ProcessGenerator { // input and output structures AstNode *always; + RTLIL::SigSpec skipSyncSignals; RTLIL::Process *proc; + const RTLIL::SigSpec &outputSignals; // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; @@ -205,7 +207,7 @@ struct AST_INTERNAL::ProcessGenerator // map helps generating nice numbered names for all this temporary signals. std::map new_temp_count; - ProcessGenerator(AstNode *always) : always(always) + ProcessGenerator(AstNode *always, RTLIL::SigSpec skipSyncSignalsArg = RTLIL::SigSpec()) : always(always), skipSyncSignals(skipSyncSignalsArg), outputSignals(subst_lvalue_from) { // generate process and simple root case proc = new RTLIL::Process; @@ -351,8 +353,10 @@ struct AST_INTERNAL::ProcessGenerator // add an assignment (aka "action") but split it up in chunks. this way huge assignments // are avoided and the generated $mux cells have a more "natural" size. - void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool noSyncToUndef = false) + void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { + if (inSyncRule) + lvalue.remove2(skipSyncSignals, &rvalue); assert(lvalue.width == rvalue.width); lvalue.optimize(); rvalue.optimize(); @@ -361,7 +365,7 @@ struct AST_INTERNAL::ProcessGenerator for (size_t i = 0; i < lvalue.chunks.size(); i++) { RTLIL::SigSpec lhs = lvalue.chunks[i]; RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks[i].width); - if (noSyncToUndef && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync")) + if (inSyncRule && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.width); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.width; @@ -1014,10 +1018,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint) break; // use ProcessGenerator for always blocks - case AST_ALWAYS: - case AST_INITIAL: { + case AST_ALWAYS: { AstNode *always = this->clone(); ProcessGenerator generator(always); + ignoreThisSignalsInInitial.append(generator.outputSignals); + delete always; + } break; + + case AST_INITIAL: { + AstNode *always = this->clone(); + ProcessGenerator generator(always, ignoreThisSignalsInInitial); delete always; } break; diff --git a/tests/k68_vltor/changes.diff b/tests/k68_vltor/changes.diff index 80d5da9d6..7b9034032 100644 --- a/tests/k68_vltor/changes.diff +++ b/tests/k68_vltor/changes.diff @@ -10,16 +10,3 @@ index 47a50c4..de27fbb 100755 } cout<<"Final sum = "<sum<<"\n"; -diff --git a/rtl/k68_clkgen.v b/rtl/k68_clkgen.v -index c201a97..55b9cad 100755 ---- a/rtl/k68_clkgen.v -+++ b/rtl/k68_clkgen.v -@@ -57,7 +57,7 @@ module k68_clkgen (/*AUTOARG*/ - assign clk4_o = cnt[1]; - assign clk_o = ~clk_i; - -- initial cnt = 0; // Power up state doesn't matter, but can't be X -+ // initial cnt = 0; // Power up state doesn't matter, but can't be X - - always @(posedge clk_i) begin - cnt <= cnt + 1'b1; diff --git a/tests/k68_vltor/run.sh b/tests/k68_vltor/run.sh index de831d38f..97ccf2389 100644 --- a/tests/k68_vltor/run.sh +++ b/tests/k68_vltor/run.sh @@ -7,7 +7,7 @@ if ( cd rtl mkdir -p ../synth - yosys -o ../synth/k68_soc.v -p 'hierarchy -check -top k68_soc; proc; opt; memory; opt' \ + ../../../../yosys -o ../synth/k68_soc.v -p 'hierarchy -check -top k68_soc; proc; opt; memory; opt' \ k68_soc.v k68_arb.v k68_cpu.v k68_load.v k68_clkgen.v k68_decode.v k68_execute.v \ k68_fetch.v k68_regbank.v k68_buni.v k68_b2d.v k68_ccc.v k68_d2b.v k68_rox.v \ k68_calc.v k68_dpmem.v k68_sasc.v sasc_brg.v sasc_top.v sasc_fifo4.v -- 2.30.2