Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrongly assign the name internal signal for vhdl #196

Open
aniketabhiraj2004 opened this issue Jun 1, 2024 · 3 comments
Open

Wrongly assign the name internal signal for vhdl #196

aniketabhiraj2004 opened this issue Jun 1, 2024 · 3 comments

Comments

@aniketabhiraj2004
Copy link

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity blink is
    port (
        clk     : in std_logic;
        inp     : in std_logic_vector(63 downto 0);
        ou      : out std_logic_vector(63 downto 0)
    );
end blink;

architecture RTL of blink is
    signal internal : std_logic;
begin
    
    process(clk) begin
        if rising_edge(clk) then
            internal <= inp(0);
            if (internal = '1') then 
                ou <= inp;
            else 
                ou <= (others => '0');     
            end if;     
            -- n
        end if;
    end process;
end RTL; 

the command i use

ghdl analyze blink_basic.vhdl
/usr/local/bin/yosys -m ghdl -p "ghdl blink; write_cxxrtl blink.cpp

the blink.cpp genrated

#include <cxxrtl/cxxrtl.h>

#if defined(CXXRTL_INCLUDE_CAPI_IMPL) || \
    defined(CXXRTL_INCLUDE_VCD_CAPI_IMPL)
#include <cxxrtl/capi/cxxrtl_capi.cc>
#endif

#if defined(CXXRTL_INCLUDE_VCD_CAPI_IMPL)
#include <cxxrtl/capi/cxxrtl_capi_vcd.cc>
#endif

using namespace cxxrtl_yosys;

namespace cxxrtl_design {

// \top: 1
struct p_blink : public module {
	/*output*/ value<64> p_ou;
	wire<64> i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_3;
	wire<1> i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2;
	/*input*/ value<64> p_inp;
	/*input*/ value<1> p_clk;
	value<1> prev_p_clk;
	bool posedge_p_clk() const {
		return !prev_p_clk.slice<0>().val() && p_clk.slice<0>().val();
	}
	p_blink(interior) {}
	p_blink() {
		reset();
	};

	void reset() override;

	bool eval(performer *performer = nullptr) override;

	template<class ObserverT>
	bool commit(ObserverT &observer) {
		bool changed = false;
		if (i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_3.commit(observer)) changed = true;
		if (i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2.commit(observer)) changed = true;
		prev_p_clk = p_clk;
		return changed;
	}

	bool commit() override {
		observer observer;
		return commit<>(observer);
	}

	void debug_eval();

	void debug_info(debug_items *items, debug_scopes *scopes, std::string path, metadata_map &&cell_attrs = {}) override;
}; // struct p_blink

void p_blink::reset() {
}

bool p_blink::eval(performer *performer) {
	bool converged = true;
	bool posedge_p_clk = this->posedge_p_clk();
	// cell \10
	if (posedge_p_clk) {
		i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2.next = p_inp.slice<0>().val();
	}
	// cells \11 \6
	if (posedge_p_clk) {
		i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_3.next = (i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2.curr ? p_inp : value<64>{0u,0u});
	}
	// connection
	p_ou = i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_3.curr;
	return converged;
}

void p_blink::debug_eval() {
}

CXXRTL_EXTREMELY_COLD
void p_blink::debug_info(debug_items *items, debug_scopes *scopes, std::string path, metadata_map &&cell_attrs) {
	assert(path.empty() || path[path.size() - 1] == ' ');
	if (scopes) {
		scopes->add(path.empty() ? path : path.substr(0, path.size() - 1), "blink", metadata_map({
			{ "top", UINT64_C(1) },
		}), std::move(cell_attrs));
	}
	if (items) {
		items->add(path, "ou", "", p_ou, 0, debug_item::OUTPUT|debug_item::DRIVEN_COMB);
		items->add(path, "internal", "", debug_alias(), i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2);
		items->add(path, "inp", "", p_inp, 0, debug_item::INPUT|debug_item::UNDRIVEN);
		items->add(path, "clk", "", p_clk, 0, debug_item::INPUT|debug_item::UNDRIVEN);
	}
}

} // namespace cxxrtl_design

extern "C"
cxxrtl_toplevel cxxrtl_design_create() {
	return new _cxxrtl_toplevel { std::unique_ptr<cxxrtl_design::p_blink>(new cxxrtl_design::p_blink) };
}

you can see that the name of signal internal whuch is internal signa, in the blink.cpp the name is given is different what is assign in vhdl code
i_auto_24_ghdl_2e_cc_3a_806_3a_import__module_24_2

how can I fix this

@tgingold
Copy link
Member

tgingold commented Jun 2, 2024

I fear this is a question for yosys, unless this problem is specific to vhdl.
If I dump the netlist in verilog, I get:

module blink(clk, inp, ou);
  wire [63:0] _0_;
  reg _1_;
  reg [63:0] _2_;
  input clk;
  wire clk;
  input [63:0] inp;
  wire [63:0] inp;
  wire internal;
  output [63:0] ou;
  wire [63:0] ou;
  always @(posedge clk)
    _1_ <= inp[0];
  always @(posedge clk)
    _2_ <= _0_;
  assign _0_ = internal ? inp : 64'h0000000000000000;
  assign internal = _1_;
  assign ou = _2_;
endmodule

So the internal signal is here. Names are probably mangled by cxxrtl writer.

@aniketabhiraj2004
Copy link
Author

Yes, it is correct for Verilog for me also, but for VHDL, it assigns different names to the internal signals.
How can I fix this.

@pat-pgt
Copy link

pat-pgt commented Nov 14, 2024

I bet this is a problem due to the latch generated. One has to handle 2 items.

The principle of the VHDL is during a process the state is prepared to be set at the end, and the process is respawned indefinitely.

Internal is a signal, not a variable. Then if the condition is true, the signal is set at the rising edge, but it blinks the input always on the next clock cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants