Yosys: Variable initial value to flip-flop at reset - yosys

I am trying to assign an initial value to the FF at reset. The initial value is an input to the circuit. In the cell library I added the following FF:
cell (DFF){
area : 0;
ff(IQ,IQN){
next_state : "D";
clocked_on : "CLK";
clear : "I'*RST";
preset : "I*RST";
clear_preset_var1 : L;
}
pin(CLK){
direction : input;
capacitance : 0;
clock : true;
}
pin(RST){
direction : input;
capacitance : 0;
}
pin(D){
direction : input;
capacitance : 0;
timing() {
related_pin : "CLK";
}
}
pin(I){
direction : input;
capacitance : 0;
}
pin(Q){
direction : output;
function : "IQ";
timing() {
related_pin : "CLK";
timing_type : falling_edge;
}
timing() {
related_pin : "RST";
timing_type : clear;
timing_sense : positive_unate;
}
timing() {
related_pin : "I";
timing_type : clear;
timing_sense : negative_unate;
}
timing() {
related_pin : "RST";
timing_type : preset;
timing_sense : positive_unate;
}
timing() {
related_pin : "I";
timing_type : preset;
timing_sense : positive_unate;
}
}
}
The part of the Verilog code that I am trying to synthesize to this FF is
always#(posedge clk or posedge rst)
if(rst) begin
e_reg <= e_input;
end
else begin
e_reg <= e_shift;
end
However, when I run the synthesis, it uses one of the built-in FFs from the Yosys library ($_DFFSR_PPP_) ignoring the one from the user-defined cell library. If I include one of the set-reset (SR) FFs in the user-defined library, like the following, that is picked up by Yosys.
cell(DFF) {
area: 0;
ff("IQ", "IQN") { clocked_on: CLK;
next_state: D;
preset: I;
clear: RST; }
pin(CLK) { direction: input;
clock: true; }
pin(D) { direction: input; }
pin(Q) { direction: output;
function: "IQ"; }
pin(I) { direction: input; }
pin(RST) { direction: input; }
}
The earlier one works with Synopsys DC, but not with Yosys. It seems that the equations in clear or preset are not being picked up by Yosys.
In there any way to make it work? Am I missing something?
EDIT: I am adding a complete example in case anyone wants to run this.
acc.v
module acc #(parameter N = 1)(
input clk,
input rst,
input [N-1:0] a,
input [N-1:0] b,
output [N-1:0] o
);
logic [N-1:0] o_reg;
assign o = o_reg & a;
always#(posedge clk or posedge rst) begin
if(rst) o_reg <= b;
else o_reg <= o;
end
endmodule
asic_cell_yosys.lib
library(demo) {
cell(IV) {
area: 1;
pin(A) { direction: input; }
pin(Z) { direction: output; function: "A'"; }
}
cell(AND) {
area: 1;
pin(A) { direction: input; }
pin(B) { direction: input; }
pin(Z) { direction: output; function: "(A&B)"; }
}
cell(NAND) {
area: 1;
pin(A) { direction: input; }
pin(B) { direction: input; }
pin(Z) { direction: output; function: "(A&B)'"; }
}
cell(DFFSR) {
area: 4;
ff("IQ", "IQN"){clocked_on: C;
next_state: D;
preset: S;
clear: R; }
pin(C) { direction: input;
clock: true; }
pin(D) { direction: input; }
pin(Q) { direction: output;
function: "IQ"; }
pin(S) { direction: input; }
pin(R) { direction: input; }
}
}
acc.tcl
yosys -import
read_verilog -sv acc.sv
hierarchy -check -top acc
procs; opt; flatten; opt;
techmap; opt;
dfflibmap -liberty asic_cell_yosys.lib
abc -liberty asic_cell_yosys.lib -script +map;
opt; clean; opt;
opt_clean -purge
write_verilog -noattr -noexpr -nohex acc_syn.v

Yosys' dfflibmap doesn't support expressions such as this for clear or preset in a Liberty file.
However, you could use the techmap command with a custom-made map rule to map $_DFFSR_PPP_ to your own flipflop - similar to how we do FPGA techmapping in Yosys.
As an example of this. Create dffsr_map.v:
module $_DFFSR_PPP_(input C, S, R, D, output Q);
DFFSR _TECHMAP_REPLACE_ (.CLK(C), .RST(S | R), .I(S), .D(D), .Q(Q));
endmodule
and add techmap -map dffsr_map.v -map +/techmap.v after dfflibmap

Related

Finding whether the binary tree is valid bst

I get Following error on running the code below for tree(2,2,2) on leetcode:
AddressSanitizer:DEADLYSIGNAL
==31==ERROR: AddressSanitizer: stack-overflow on address 0x7ffe3ba89ff8 (pc 0x000000372df9 bp 0x7ffe3ba8a010 sp 0x7ffe3ba8a000 T0)
==31==ABORTING
My code is given below:
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode* cur=root;
while(cur){
cout<<cur->val<<endl;
if(!cur->left) {
if(!cur->right) return 1;
int a=cur->val,b=cur->right->val;
if(a>=b )
return false;
cur=cur->right;
}
else{
TreeNode* prev=cur->left;
while(prev->right && prev->right!=cur)
prev=prev->right;
if(prev->right==NULL){
prev->right=cur;
cur=cur->left;
}
else{
prev->right=0;
if(cur->val>=cur->right->val) return 0;
cur=cur->right;
}
}
}
return 1;
}
};

Port not bound SystemC (E112)

I am trying to implement a producer (master) speaking to a memory element (slave) through the memory controller (which implements the interface simple_mem_interface).
Note: Some functions details and include statements are not fully mentioned in the code attached.
Searching for bugs in the code.
Adding debugging tools to find the fault in Write Enable Port.
binding.cpp
int sc_main(int argc, char* argv[])
{
sc_signal<unsigned int> d_out,d_in,address_d;
sc_signal<bool> wen, ren, ack;
sc_clock ClkFast("ClkFast", 100, SC_NS);
sc_clock ClkSlow("ClkSlow", 50, SC_NS);
Memory_Controller Controller1 ("Controller");
d_out = Controller1.data_mem_read;
ren.write(Controller1.REN);
ack.write(Controller1.ack);
d_in.write(Controller1.data_write);
address_d.write(Controller1.address);
wen.write(Controller1.WEN);
producer P1("Producer");
P1.out(Controller1);
P1.Clk(ClkFast);
Memory_module MEM("Memory");
MEM.Wen(wen);
MEM.Ren(ren);
MEM.ack(ack);
MEM.Clock(ClkSlow);
MEM.data_in(d_in);
MEM.data_out(d_out);
MEM.address(address_d);
sc_start(5000, SC_NS);
return 0;
Memory_controller.h
#define MEM_SIZE 100
#include <interface_func.h>
class Memory_Controller : public sc_module, public simple_mem_if
{
public:
// Ports
sc_in <unsigned int> data_mem_read{ "Data_Read_from_Memory" };
sc_out<bool> REN { "Read_Enable" };
sc_out<bool> WEN { "Write_Enable" };
sc_out <bool> ack{ "ACK_Bool" };
sc_out<unsigned int> address{ "Memory_Address" }, data_write{
"Data_Written_to_Memory" };
// constructor
Memory_Controller(sc_module_name nm) : sc_module(nm)
{ // Creating a 2 dimentional array holding adresses and data
WEN.write(false);
REN.write(false);
ack.write(false);
}
~Memory_Controller() //destructor
{
}
bool Write(unsigned int address_i, unsigned int datum) // blocking write
{
WEN.write(true);
REN.write(false);
data_write.write(datum);
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
bool Read(unsigned int address_i, unsigned int& datum_i) // blocking read
{
WEN.write(false);
REN.write(true);
datum_i=data_mem_read;
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
void register_port(sc_port_base& port, const char* if_typename)
{
cout << "binding " << port.name() << " to "
<< "interface: " << if_typename << endl;
}
};
Memory.h
#define MEM_SIZE 100
#include "interface_func.h"
class Memory_module : public sc_module
{
public:
sc_in<bool> Wen,Ren;
sc_in <unsigned int> address, data_in ;
sc_in<bool> Clock;
sc_out <unsigned int> data_out;
sc_out <bool> ack;
bool fileinput = false;
ifstream myfile;
unsigned int item [MEM_SIZE];
Memory_module()
{
}
void Write() // blocking write
{
while (true)
{
wait();
if (Wen==true)
{
if (address >= MEM_SIZE || address < 0)
{
ack=false;
}
else
{
item[address]=data_in;
ack=true;
}
}
}
}
void Read() // blocking read
{
while (true)
{
wait();
if (Ren)
{
if (address >= MEM_SIZE || address < 0)
ack=false;
else
{
data_out.write(item[address]);
ack=true;
}
}
}
}
SC_CTOR(Memory_module)
{
SC_THREAD(Read);
sensitive << Clock.pos();
SC_THREAD(Write);
sensitive << Clock.pos();
}
};
interface_func.h
class simple_mem_if : virtual public sc_interface
{
public:
virtual bool Write(unsigned int addr, unsigned int data) = 0;
virtual bool Read(unsigned int addr, unsigned int& data) = 0;
};
After debugging the SystemC binder.cpp code, the following error arises:
(E112) get interface failed: port is not bound : port 'Controller.Write_Enable' (sc_out)
You cannot drive your unconnected ports in the Memory_Controller constructor. If you want to explicitly drive these ports during startup, move these calls to a start_of_simulation callback:
Memory_Controller(sc_module_name nm) : sc_module(nm)
{}
void start_of_simulation()
{
WEN.write(false);
REN.write(false);
ack.write(false);
}

Changing signal on every posedge of clock in SC_THREAD

I want to implement module, which when is called to work changes signal x the way below:
1 clk pos.edge : x = 0 // 1st phase
2 clk pos.edge : x = 0 // 2nd phase
3 clk pos.edge : x = 1 // 3rd phase
And then stops until called again.
I have function foo() in my module, which is called from main and allows thread work_foo() to execute on the posedge of clock.
I tried to do it this way (with wait()), and in some simple test it gives right wave, but it is an inappropriate way: my_module.h:
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{ // foo() was called
if (phase == 0)
{
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_1;
wait(); // waiting for the next tick
}
else
{
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
}
};
main.cpp:
#include "systemc.h"
#include "my_module.h"
int sc_main (int argc, char* argv[])
{
sc_clock clock("clock", 10, SC_NS);
sc_signal<sc_logic > x;
my_module mm("my_mod");
mm.clk(clock);
mm.x(x);
mm.foo ();
sc_start(200, SC_NS);
sc_stop();
return 0;
}
And now I'm trying to implement it another way. I was advised to use additional sc_signal (or variable) in my module, which indicates the incrementing number of the phase. The problem is what this gets looped at the very start. How can I solve this?
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
sc_signal <uint> phase;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{
if (phase == 0)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 1)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 2)
{
x = SC_LOGIC_1;
phase=phase+1;
}
}
else
{
phase=0;
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
phase=0;
}
};

Write out a triangulation result to an OBJ file in CGAL

I'm trying to make use of a 2D triangulation using CGAL, and create an obj file. I'm able to create a 2D triangulation. I now want to make the 3rd coordinate 0, ie z=0, and create a obj file out of the result of the triangulation. The samples of CGAL seem quite confusing, and I'm not sure how to go about this.
Here is how I did it. Hope it helps someone.
// A modifier creating a triangle with the incremental builder.
template<class HDS>
class polyhedron_builder : public CGAL::Modifier_base<HDS> {
public:
std::vector<Triangulation>& t_;
polyhedron_builder(std::vector<Triangulation>& t) : t_(t) {}
void operator()(HDS& hds) {
typedef typename HDS::Vertex Vertex;
typedef typename Vertex::Point Point3;
// create a cgal incremental builder
CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true);
// calculte total vertices
int face_num = 0;
int vertice_num = 0;
for (auto& tri : t_) {
face_num += tri.number_of_faces();
vertice_num += tri.number_of_vertices();
}
std::cout << face_num << ", " << vertice_num << ", " << t_.size() << "\n";
B.begin_surface(face_num, vertice_num);
// add the polyhedron vertices
for (auto& tri : t_) {
for (auto itr = tri.finite_vertices_begin(); itr != tri.finite_vertices_end(); ++itr) {
B.add_vertex(Point3(itr->point().x(), itr->point().y(), 0));
}
}
// add the polyhedron triangles
for (auto& tri : t_) {
for (auto itr = tri.finite_faces_begin(); itr != tri.finite_faces_end(); ++itr) {
B.begin_facet();
B.add_vertex_to_facet(itr->vertex(0)->info());
B.add_vertex_to_facet(itr->vertex(1)->info());
B.add_vertex_to_facet(itr->vertex(2)->info());
B.end_facet();
}
}
// finish up the surface
B.end_surface();
}
};
void OBJfile::write_obj_file(const std::string& filename) {
CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>> polyhedron;
unsigned index = 0;
std::vector<Triangulation> t_vector;
// here, contours is an internal object that tracks the polygon outlines
for (auto& contour : contours_) {
Triangulation t;
std::vector < std::pair<Point, unsigned> > polygon;
for (auto& pt : contour) {
Point point(pt.x(), pt.y());
polygon.push_back(std::make_pair(point, index++));
}
triangulate(polygon, t);
t_vector.push_back(t);
}
polyhedron_builder<HalfedgeDS> builder(t_vector);
polyhedron.delegate(builder);
// write the polyhedron out as a .OFF file
std::ofstream os("test.obj");
CGAL::File_writer_wavefront writer;
CGAL::generic_print_polyhedron(os, polyhedron, writer);
os.close();
}
void OBJfile::triangulate(const std::vector<std::pair<Point, unsigned>>& polygon_points, Triangulation& t) {
auto begin = polygon_points.begin();
auto end = polygon_points.end();
//std::istream_iterator<Point> end;
t.insert(begin, end);
}

how to find the first and follow values of grammar

i have the following grammar and i would like to create the First & follow table. if i have a case that the first of non terminal is epsilon should i take also all the terminals that came after this non terminal from is rule?
S-> ABC
A->Aa/aB
B->Bb/epsilon
C->Cc/epsilon
and my question is:
in the first of C i need to get First(C) = {epsilon,c) and First(B) = {epsilon,b)?
i got the following results but still i think i have problems:
|first|follow
S |a |$
A |a |a
B |eps,b|b,a,$
C |eps,c|$
Finding the FIRST and Follow of a Grammar written in txt FILE:
#include<stdio.h>
#include<string.h>
#define size 10
int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[size],temp,temp2[size],temp3[20],*ptr;
struct prod
{
char left_of_non_term[size],right_of_nonTerm[size][size],first[size],fol[size];
int n;
}pro[size];
int main()
{
FILE *f;
for(i=0;i<size;i++)
pro[i].n=0;
f=fopen("lab6.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].left_of_non_term);
if(n>0)
{
if( strcmp(pro[n].left_of_non_term,pro[n-1].left_of_non_term) == 0 )
{
pro[n].left_of_non_term[0]='\0';
fscanf(f,"%s",pro[n-1].right_of_nonTerm[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].right_of_nonTerm[pro[n].n]);
pro[n].n++;
n++;
}
printf("\nGiven Grammar");
printf("\n-------------\n");
for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s = %s\n",pro[i].left_of_non_term,pro[i].right_of_nonTerm[j]);
pro[0].first[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].right_of_nonTerm[j][0]<65 || pro[i].right_of_nonTerm[j][0]>90 )
{
pro[i].first[strlen(pro[i].first)]=pro[i].right_of_nonTerm[j][0];
}
else if( pro[i].right_of_nonTerm[j][0]>=65 && pro[i].right_of_nonTerm[j][0]<=90 )
{
temp=pro[i].right_of_nonTerm[j][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
}
printf("-------------");
printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].first);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].first[l]==pro[i].first[j])
break;
if(l==-1)
printf("%c ",pro[i].first[j]);
}
printf("}");
}
for(i=0;i<n;i++)
temp2[i]=pro[i].left_of_non_term[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].right_of_nonTerm[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].right_of_nonTerm[j];
if(pro[l].right_of_nonTerm[j][p+1]>=65 && pro[l].right_of_nonTerm[j][p+1]<=90)
{
for(o=0;o<n;o++)
if(pro[o].left_of_non_term[0]==pro[l].right_of_nonTerm[j][p+1])
strcat(pro[i].fol,pro[o].first);
}
else if(pro[l].right_of_nonTerm[j][p+1]=='\0')
{
temp=pro[l].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].right_of_nonTerm[j][p+1];
}
}
}
}
printf("\n\n\n");
for(i=0;i<n;i++)
{
printf("\nFOLLOW (%s) -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
printf(" }");
}
printf("\n");
//getch();
}
void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].left_of_non_term[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].right_of_nonTerm[t][0]<65 || pro[k].right_of_nonTerm[t][0]>90 )
pro[i].first[strlen(pro[i].first)]=pro[k].right_of_nonTerm[t][0];
else if( pro[k].right_of_nonTerm[t][0]>=65 && pro[k].right_of_nonTerm[t][0]<=90 )
{
temp=pro[k].right_of_nonTerm[t][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
break;
}
}
}
void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].right_of_nonTerm[t],temp);
if( ptr1 )
{
p1=ptr1-pro[k].right_of_nonTerm[t];
if(pro[k].right_of_nonTerm[t][p1+1]>=65 && pro[k].right_of_nonTerm[t][p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].left_of_non_term[0]==pro[k].right_of_nonTerm[t][p1+1])
{
strcat(pro[i].fol,pro[o1].first);
chk++;
}
}
else if(pro[k].right_of_nonTerm[t][p1+1]=='\0')
{
temp=pro[k].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].right_of_nonTerm[t]
[p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}
Also Make a text File named it lab6.txt . and put grammers like below
S ABCDE
A a|0
B b|0
C c
D d|0
E e|0
Here space after NonTerminal Indicates the -> this sign and 0 indicates epsilon.