Synthesizing SystemC with Vivado doesn't give desired VHDL signals - synthesis

I am writing a project is systemC and i have a couple of sc_in<bool> and sc_out<bool> to communicate between my modules. When I synthesize the project, in the vhdl code produced each sc_in and sc_out creates a block of signals like this:
valid_in_address0 : OUT STD_LOGIC_VECTOR (2 downto 0);
valid_in_ce0 : OUT STD_LOGIC;
valid_in_we0 : OUT STD_LOGIC;
valid_in_d0 : OUT STD_LOGIC_VECTOR (0 downto 0);
valid_in_q0 : IN STD_LOGIC_VECTOR (0 downto 0);
valid_in_address1 : OUT STD_LOGIC_VECTOR (2 downto 0);
valid_in_ce1 : OUT STD_LOGIC;
valid_in_we1 : OUT STD_LOGIC;
valid_in_d1 : OUT STD_LOGIC_VECTOR (0 downto 0);
valid_in_q1 : IN STD_LOGIC_VECTOR (0 downto 0);
This is way too complicated as for my hardware design as I only want to have 1 signal declared like this:
valid_in : IN STD_LOGIC
Declaring a variable as sc_bit, I had no problem with the generated VHDL but after I tried using sc_in<sc_bit> instead of sc_in<bool> in my signals to communicate between modules the project does not compile anymore. If I assign values like this:
sc_bit asdf = 0;
I get the following message:
../../../../source.cpp:67:16: error: conversion from 'int' to
non-scalar type 'sc_dt::sc_bit' requested
If I assign values like this:
sc_bit asdf = '0';
I get the following message:
../../../../source.cpp:68:14: error: no match for 'operator=' in
'((source*)this)->source::asdf = '0''
Is there any other way to declare I/O signals in SystemC so that after synthesis I will only have 1 std_logic signal in VHDL?
The SC_MODULE for the source in the testbench goes like this
header file:
# ifndef SOURCE_H
# define SOURCE_H
# include "systemc.h"
using namespace std;
SC_MODULE(source) {
sc_in_clk clk;
sc_out<sc_bit > valid_out;
void do_cycle();
SC_CTOR(source) {
{
//irrelevant initializations
}
SC_THREAD(do_cycle) {
//i know sc_thread is unsynthesizable but source is testbench
//and i need the signal to be sc_out<sc_bit> to give it as
//input in my top function to be synthesized
}
};
#endif //SOURCE_H
cpp file:
#include "source.h"
void source::do_cycle() {
valid_out = '0';
while(true) {
wait(clk.posedge_event());
//do different kind of stuff
}
}

Related

Error (10500): VHDL syntax error at big_adder.vhd(24) near text ""; expecting ")", or ","

Im getting this error on quartus about a syntax error, but Cannot find it:
The program is an generic adder for 8 bits
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY big_adder IS
PORT (a, b: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
cin: IN STD_LOGIC;
sum: OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
cout: OUT STD_LOGIC);
END big_adder;
ARCHITECTURE big_adder OF big_adder IS
SIGNAL carry: STD_LOGIC_VECTOR(8 DOWNTO 0);
COMPONENT carry_lookahead_adder IS
PORT (a, b: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
cin: IN STD_LOGIC;
sum: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
cout: OUT STD_LOGIC);
END COMPONENT;
BEGIN
carry(0) <= cin;
gen_adder: FOR i IN 1 TO 8 GENERATE
adder: carry_lookahead_adder PORT MAP(a(4*i–1 DOWNTO 4*i–4), b(4*i–1 DOWNTO 4*i–4), carry(i–1), sum(4*i–1 DOWNTO 4*i–4), carry(i));
END GENERATE;
cout <= carry(8);
END big_adder;big_adder;
The syntax looks valid, except of the last line
END big_adder;big_adder;
You have to remove one of the "big_adder;".
One personal hint: You should train yourself to write clean code from day 1!

Translating a VHDL code to Verilog compilation error

I'm translating a VHDL code to Verilog but I have a question in VHDL:
What is the use of the concatenation with the empty string in these lines?
Xp_m5b0 <= XX_m5(23 downto 0) & "";
Yp_m5b0 <= YY_m5(23 downto 0) & "";
It is said that it changes the type, but the types here are the same (std_logic_vector).
Here are the lines that showed the type:
entity IntMultiplier_LogicOnly_24_24_48_unsigned_F400_uid4 is
port ( clk, rst : in std_logic;
X : in std_logic_vector(23 downto 0);
Y : in std_logic_vector(23 downto 0);
R : out std_logic_vector(47 downto 0) );
end entity;
signal XX_m5 : std_logic_vector(23 downto 0);
signal YY_m5 : std_logic_vector(23 downto 0);
signal Xp_m5b0 : std_logic_vector(23 downto 0);
signal Yp_m5b0 : std_logic_vector(23 downto 0);
XX_m5 <= X ;
YY_m5 <= Y ;
In verilog after translation, this concatenation gives a compilation error:
assign Xp_m5b0 = {XX_m5[23:0], 0'b };
assign Yp_m5b0 = {YY_m5[23:0], 0'b };
So does it have a difference in the meaning if I removed it and made it like this:
assign Xp_m5b0 = XX_m5[23:0];
assign Yp_m5b0 = YY_m5[23:0];
"" is not an empty string, but an empty array. I haven't seen it used in this context, but it can be used to convert a literal to an array. I.e. consider the next code:
entity e is end entity;
library ieee;
architecture a of e is
use ieee.std_logic_1164.all;
signal a : std_logic_vector(0 downto 0);
signal b : std_logic;
begin
-- a <= b; -- fails
a <= b&""; -- works
end architecture;
But since XX_m5(23 downto 0) is already an array (slice), it should not be required here...

VHDL Vector passing

I want to pass a value from one vector to another.
Can I simply do it this way?
vector_one : out STD_LOGIC_VECTOR (3 downto 0);
vector_two : out STD_LOGIC_VECTOR (3 downto 0);
vector_one <= vector_two;
The vector_one is an output port (mode out), and reading this is allowed in VHDL-2008, so you can do:
vector_one <= vector_two;
However, in VHDL-2002 it is not allowed to read an output port, so you must drive both outputz from the source, say vector_source, like:
vector_one <= vector_source;
vector_two <= vector_source;
Generally, it should be avoided to duplicate an output signal like that, since it is not obvious from the use of that module that some output are driven with identical values, which makes it harder to understand the module use.
you can but you need to take note that if you will need to use vector_one in your module before it gets used outside meaning that the module will need to hold information about it. Then you will need to declare an internal signal in order to work on it.
example:
entity exampleModule is
port( iClk : in STD_LOGIC;
iTrigger : in STD_LOGIC;
iVector_one : out STD_LOGIC_VECTOR (3 downto 0);
oVector_two : out STD_LOGIC_VECTOR (3 downto 0));
end exampleModule ;
Architecture RTL of exampleModule is
signal mVectorBuff : std_logic_vector (3 downto 0);
begin
process (iClk) begin
if rising_edge (iClk) then
if iTrigger then mVectorBuff <= iVector_one;
end if;
end if;
end process;
oVector_two <= mVector_one;
end Architecture RTL;

Shift Register for std_logic_vector

I saw the same question here and i tried to follow the example but i ran into errors when declaring my signals. In specific:
#Error: COMP96_0015: Pipeline.vhd : (52, 44): ';' expected.
Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Pipeline isgeneric (
VECTOR_WIDTH: natural := 128;
VECTOR_DEPTH: natural := 7
); port(
ImVal : in STD_LOGIC_VECTOR(9 downto 0);
RA : in STD_LOGIC_VECTOR(127 downto 0);
RB : in STD_LOGIC_VECTOR(127 downto 0);
RC : in STD_LOGIC_VECTOR(127 downto 0);
OpCode : in STD_LOGIC_VECTOR(10 downto 0);
RT : in STD_LOGIC_VECTOR(127 downto 0);
Clk: in STD_LOGIC;
Reset: in STD_LOGIC;
OutVal : out STD_LOGIC_VECTOR(127 downto 0)
);
end Pipeline;
architecture Behavioral of Pipeline is
type shift_reg_type1 is array (natural range<>) of std_logic_vector(127 downto 0);
type shift_reg_type2 is array (natural range<>) of std_logic_vector(10 downto 0);
type shift_reg_type3 is array (natural range<>) of std_logic_vector(9 downto 0);
signal shift_regA: shift_reg_type1(0 to 6)(127 downto 0);
signal shift_regB: shift_reg_type1(0 to 6)(127 downto 0);
signal shift_regC: shift_reg_type1(0 to 6)(127 downto 0);
signal shift_regT: shift_reg_type1(0 to 6)(127 downto 0);
signal OpCode_reg: shift_reg_type2(0 to 6)(10 downto 0);
signal ImVal_reg: shift_reg_type3(0 to 6)(9 downto 0);
begin
end Behavioral;
It is complaining about my signal declarations but i do not understand why.
The signal declarations are wrong as the error message say. Moreover it expects a semicolon because the statement is complete, but your code has two range constraints per signal...
signal shift_regA: shift_reg_type1(0 to 6);
signal shift_regB: shift_reg_type1(0 to 6);
signal shift_regC: shift_reg_type1(0 to 6);
signal shift_regT: shift_reg_type1(0 to 6);
signal OpCode_reg: shift_reg_type2(0 to 6);
signal ImVal_reg: shift_reg_type3(0 to 6);
shift_reg_type1 is already constraint to 127..0. So can't constraint shift_regA again in the second dimension. Btw. there is no second dimension, because it's a 1 dimensional array of 1 dimensional elements.

How to initialize signal using .mif file

For example, I have behavioral definition of ROM:
ENTITY rom_4x4_behavioral IS
PORT (address : IN NATURAL RANGE 0 TO 7;
q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END entity;
ARCHITECTURE rom_4x4_behavioral_arch OF rom_4x4_behavioral IS
SUBTYPE word IS STD_LOGIC_VECTOR(3 DOWNTO 0);
TYPE memory IS ARRAY(7 downto 0) OF word;
SIGNAL rom : memory;
SIGNAL addr_reg : NATURAL RANGE 0 TO 7;
BEGIN
PROCESS (address)
BEGIN
addr_reg <= address;
END process;
q <= rom(addr_reg);
END rom_4x4_behavioral_arch;
What do I have to do to initialize rom signal using .mif file?
Writing a .mif file parser in VHDL would be a lot of work to do.
If you are using the Quartus-II toolchain, then you could also generate a ROM by the Megawizard Plugin Manager (see menu tools). In the wizard you can specifiy the organization of your ROM as well as the .mif file with the initial data.
If you don't want to use that or if you are using other toolchains, then a text file in (Xilinx) .mem format would be another option. A sample implementation of how to read initialization data from such a text file can be found in the VHDL Library PoC in the namespace PoC.mem.ocrom.

Resources