EDA工具是怎樣建模大規模數字集成電路的?RTL代碼被讀取以後,使用怎樣的模型/數據結構進行存儲的?

數字IC的EDA工具對大規模的電路處理,大多是從對RTL代碼或者Netlist文件的讀入開始。當EDA工具讀入代碼之後,會在內部建立數據模型,以便後續進行處理,請問怎樣的數據結構才能高效地對電路進行建模,同時方便後續處理,謝謝!


EDA軟體一般用directed acyclic graph (DAGs) 表示netlist,但是在具體的階段會有更為有效的數據結構來表示DAGs.

在前端邏輯綜合階段,technology independent的邏輯綜合用到的數據結構是binary decision diagram (BDD),technology mapping時用到的則是and-inverter graph (AIG). 你可以參考UCB的邏輯綜合軟體ABC.

驗證階段像formal verification用到的也是BDD.

後端的physical design階段總體而言還是用DAGs,有時候為了更為高效的實現某些演算法可能需要設計對應的數據結構。


學過一點EDA,稍微懂一點。我主要說一下模擬方面的東西,其他的placement和布線和physical design之類的是另外的東西,我具體不是很懂

其實數字和模擬電路的模擬(DC AC Transient analysis)本質上是一樣的,反正都是電路嘛。 這裡推薦一本eda的入門書籍:Electronic Circuit and System Simulation Methods, Lawrence T. Pillage (這第一個作者是CMU大牛)

我要說的是netlist級的模擬(算是後仿),不是rtl級單純從logic這一級的模擬。

主要的idea就是對電路元件進行建模,有linear和nonlinear的元件,都可以找出linear的公式描述,然後根據KCL和KVL列出方程組,最後轉化為求解線性系統 Ax = b

回到你具體的問題,首先要有一個parser讀netlist(網表),構建你要模擬的電路。用來描述電路的數據結構通常是Undirected graph,每一條邊代表一個電路元件(RLC mosfet 等)每一個節點一般來說就是存一個電壓,再複雜一些的話,會存接地的RC值

這個圖通常會特別大,對於數字電路來說的話。所以一般是特別compact的。我是見過有bucket array來描述這些連接關係的。

有了這個圖之後,你就可以構建線性系統了,一般用「stamping」的辦法構建那個矩陣A,然後用一般用solver進行求解。

這些主要是DC和transient analysis的東西,AC稍微有點不一樣,但是原理是相通的,而且AC在數字電路的模擬中遇到的不多。

這些大概就是模擬的東西了吧,具體怎麼構建矩陣和如何對電路元件建模,請看我說的那本書,需要的話我可以email給你。

希望這些對你有點幫助。


以前弄sizing的時候弄過一個tool, 因為是用C寫的, 所以當時就是用各種指針來的.

主要的存儲結構就是node, gate.(有沒有port類型記不清了)

gate會記錄這個是哪個gate, 名字和類型, 有幾個連接的port, 每個port連接到哪個node, 當然還有各種cap什麼的就不說了.

node就是記錄這個node和那幾個port以及哪幾個gate相連.

這樣基本就已經是存儲了整個netlist了, 然後就可以通過input和output來推算driving ability來做sizing了

我覺得這個應該就是一個比較簡單的存儲模型了吧


可以參考icarus verilog的源碼,就是和modelsim一樣的模擬程序,正如匿名回答說的一樣,和普通編譯器沒什麼兩樣。

icarus是編譯verilog到一個叫做vvp的中間文件,然後用程序附帶的vvp解釋器去讀vvp文件,然後根據test bench的要求生成vcd,然後用gtkwave看波形。

vvp是個文本文件,reg用類似bitvec的東西模擬,wire用……我也不知道怎麼表達,就是直接調用。

題主想要的模型應該就體現在vvp文件裡面。

別的我就不懂了。Orz


這是本人自製的一款綜合器的源代碼,用C寫成,數據結構只用了鏈表,請多指教

#include &
#include &
#include &
#include & FILE *fp;
int n,n1,n2,ee_name_len,count,count_in,count_out,st,*p,qua,allcov,sign;
char a[10000],file[20],filetxt[30],filectt[30],ee_name[20],v_name[20],clock_not[20],reset_not[20],reg_string[20];
typedef struct in
{
char name[20];
int num;
struct in *p;
}IN;
typedef struct sm
{
char name[20];
int start,end;
}SM;
typedef struct rv
{
IN *in_p;
struct rv *p;
}RV;
typedef struct num
{
int n;
struct num *p;
}NUM;
typedef struct ee1
{
IN *in_p;
int in_st,addr;
struct ee1 *p;
}EE1;
typedef struct ee2
{
int val,addr;
struct ee2 *p;
}EE2;
typedef struct not
{
int in,num;
struct not *p;
}NOT;
typedef struct and
{
NUM in_head,r_head,rn_head,not_head;
int num;
struct and *p;
}AND;
typedef struct or
{
NUM in_head,r_head,rn_head,not_head,and_head;
int num;
struct or *p;
}OR;
typedef struct ive
{
int num,st;
struct ive *p;
}IVE;
typedef struct de
{
int st;
IVE ive_head;
struct de *p;
}DE;
typedef struct imp
{
IVE ive_head;
int idx,num;
struct imp *p;
}IMP;
typedef struct bf
{
int idx;
IMP imp_head;
}BF;
typedef struct tt
{
short val,idx;
}TT;
typedef struct out
{
char name[20];
EE1 ee1_head;
EE2 ee2_head;
RV rv_head;
DE de_head;
TT *tt;
BF bf;
int num,idx,dnum,clear_type,clock_edge,clear_edge;
struct out *p;
}OUT;
typedef struct pa
{
char name[20];
int start,end;
NUM val_head;
struct pa *p;
}PA;
typedef struct bl
{
int start,end;
struct bl *p;
}BL;
typedef struct gc
{
IN *in_p;
int st,start,end;
struct gc *p;
}GC;
typedef struct sv
{
char name[20];
struct sv *p;
}SV;
typedef struct er
{
int st,start,end;
struct er *p;
}ER;
typedef struct tsg
{
int ena,data,d_idx,num;
char out_name[20];
struct tsg *p;
}TSG;
typedef struct output
{
char name[20];
int num;
struct output *p;
}OP;
IN in_head,*in,*clock,*reset;
OUT out_head,*out,*out1;
NUM num_head,*num,*val,*iu,*ru,*rnu,*nu,*au;
PA pa_head,*pa;
BL bl_head,*bl,al_head,*al;
GC gc_head,*gc,*gc1;
SV sv_head,*sv,*sv1;
EE1 *ee1;
EE2 *ee2;
RV *rv,*rv1;
SM sm;
DE *de;
IVE *ive,*ive1;
TT *tt;
IMP *imp;
NOT not_head,*not,*not1;
AND and_head,*and,*and1;
OR or_head,*or;
ER er_head,*er;
TSG tsg_head,*tsg;
OP op_head,*op;
void main()
{
void extract(),find_var(),find_sm(),find_pa(),find_bl(),find_gc(),find_smc(),find_sv(),find_ee(),form_rv(),form_de(),form_tt(),form_bf(),form_nl(),display(),clear();
while(1)
{
extract();
find_var();
find_sm();
find_pa();
find_bl();
find_gc();
find_smc();
find_sv();
find_ee();
form_rv();
form_de();
form_tt();
form_bf();
form_nl();
display();
clear();
}
}
void extract()
{
int i;
for(i=0;i&<10000;i++) a[i]=0; printf("請輸入要綜合的RTL級Verilog源文件的名稱:"); s1:gets(file); strcpy(filetxt,file); strcat(filetxt,".txt"); if((fp=fopen(filetxt,"r"))==NULL) { printf(" 文件%s不存在,請重新輸入Verilog源文件名稱:",filetxt); goto s1; } for(i=0;(a[i]=fgetc(fp))!=EOF;i++); a[i]=0; fclose(fp); printf(" %s的門級網表正在綜合中,請稍等… ",filetxt); } void find_var() { void input(),inout(),reg(); count_in=count_out=0; in=in_head; out=out_head; input(); inout(); reg(); } void find_sm() { char c[20]; int i,j,cmp(); void first(); for(i=0;!cmp(a[i],"case(")a[i];i++); for(i+=5,j=0;a[i]!=")";i++,j++) sm.name[j]=a[i]; sm.name[j]=0; strcpy(c,"case("); strcat(c,sm.name); strcat(c,")"); first(c); sm.start=n; strcpy(c,"endcase"); first(c); sm.end=n; } void find_pa() { int i,j,cmp(); void next_pa(); for(n=0;!cmp(a[n],"parameter ")a[n];n++); n1=n+10; for(;!cmp(a[n],";")a[n];n++); n2=n; for(n=n1,pa=pa_head;n&p=calloc(1,sizeof(PA));
for(i=n,j=0;a[i]!=" "a[i]!="=";i++,j++)
pa-&>p-&>name[j]=a[i];
pa-&>p-&>name[j]=0;
for(i=n;a[i]!=","a[i]!=";";i++);
for(i--,val=pa-&>p-&>val_head;a[i]=="0"||a[i]=="1";i--)
{
val-&>p=calloc(1,sizeof(NUM));
val-&>p-&>n=a[i]-48;
val=val-&>p;
}
pa=pa-&>p;
}
}
void find_bl()
{
int i,cmp();
void first(),next();
bl=bl_head;
for(first("begin");a[n];next("begin"))
{
bl-&>p=calloc(1,sizeof(BL));
bl-&>p-&>start=n;
count=0;
for(i=n+5;a[i];i++)
{
if(cmp(a[i],"begin")) count++;
else if(cmp(a[i],"end"))
{
if(count!=0) count--;
else {bl-&>p-&>end=i+2; break;}
}
}
bl=bl-&>p;
}
}
void find_gc()
{
char name[20];
int i,j,cmp(),get_range();
void first(),next(),get_else();
gc=gc_head;
for(first("if(");a[n];next("if("))
{
gc-&>p=calloc(1,sizeof(GC));
if(a[n+3]!="!") {i=n+3; gc-&>p-&>st=1;}
else {i=n+4; gc-&>p-&>st=0;}
for(j=0;a[i]!=")";i++,j++)
name[j]=a[i];
name[j]=0;
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(name,in-&>p-&>name)) {gc-&>p-&>in_p=in-&>p; break;}
i=get_range();
for(i++;a[i]&<"a"||a[i]&>"z";i++);
if(cmp(a[i],"else")) get_else(i,in-&>p,gc-&>p-&>st);
gc=gc-&>p;
}
}
void find_smc()
{
int i,j,temp;
char c[20];
void first(),next();
for(pa=pa_head,count=0;pa-&>p!=NULL;pa=pa-&>p,count++)
{
strcpy(c,pa-&>p-&>name);
strcat(c,":");
for(first(c);a[n-1]&>="a"a[n-1]&<="z";next(c)); pa-&>p-&>start=n;
}
p=(int*)calloc(count,sizeof(int));
for(pa=pa_head,i=0;pa-&>p!=NULL;pa=pa-&>p,i++)
*(p+i)=pa-&>p-&>start;
for(i=0;i&<=count-2;i++) for(j=0;j&<=count-2-i;j++) if(*(p+j)&>*(p+j+1))
{
temp=*(p+j);
*(p+j)=*(p+j+1);
*(p+j+1)=temp;
}
for(pa=pa_head;pa-&>p!=NULL;pa=pa-&>p)
for(i=0;i&<=count-1;i++) if(*(p+i)==pa-&>p-&>start)
{
if(i!=count-1) pa-&>p-&>end=*(p+i+1)-1;
else {first("endcase"); pa-&>p-&>end=n-1;}
}
free(p);
}
void find_sv()
{
void edge(),dif_spe(),get_clock();
sv=sv_head;
edge("posedge");
edge("negedge");
dif_spe();
get_clock();
}
void find_ee()
{
int i,idx,s,cmp(),check_num();
void ge_ee(),sm_ee();
count=0;
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
ee1=out-&>p-&>ee1_head;
ee2=out-&>p-&>ee2_head;
if(!cmp(out-&>p-&>name,sm.name))
{
if(check_num(out-&>p-&>name))
{
for(i=0;out-&>p-&>name[i]!="[";i++)
ee_name[i]=out-&>p-&>name[i];
ee_name[i]=0;
for(;out-&>p-&>name[i]!="]";i++);
for(idx=0,i--,s=1;out-&>p-&>name[i]!="[";i--,s*=10)
idx+=s*(out-&>p-&>name[i]-48);
strcat(ee_name,"&<="); ee_name_len=strlen(ee_name); ge_ee(idx); } strcpy(ee_name,out-&>p-&>name);
strcat(ee_name,"&<="); ee_name_len=strlen(ee_name); ge_ee(-1); } else { strcpy(ee_name,sm.name); strcat(ee_name,"&<="); ee_name_len=strlen(ee_name); sm_ee(); count++; } } } void form_rv() { int cmp(),check_sm(); void smcv(),gcv(),asnv(),sfv(); for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
rv=out-&>p-&>rv_head;
if(cmp(out-&>p-&>name,sm.name)||check_sm()) smcv();
gcv();
asnv();
sfv();
}
}
void form_de()
{
void ee1_de(),ee2_de();
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
de=out-&>p-&>de_head;
for(ee1=out-&>p-&>ee1_head;ee1-&>p!=NULL;ee1=ee1-&>p)
{
n=ee1-&>p-&>addr;
ee1_de(0);
ee1_de(1);
}
for(ee2=out-&>p-&>ee2_head;ee2-&>p!=NULL;ee2=ee2-&>p)
{
n=ee2-&>p-&>addr;
ee2_de();
}
}
}
void form_tt()
{
void pre_asn(),de_asn();
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
for(rv=out-&>p-&>rv_head,n=0;rv-&>p!=NULL;rv=rv-&>p,n++);
count=(int)pow(2,n);
tt=out-&>p-&>tt=(TT*)calloc(count,sizeof(TT));
p=(int*)calloc(n,sizeof(int));
pre_asn();
de_asn();
free(p);
}
}
void form_bf()
{
int scan();
void combine(),sieve();
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
tt=out-&>p-&>tt;
imp=out-&>p-&>bf.imp_head;
for(rv=out-&>p-&>rv_head,n=0;rv-&>p!=NULL;rv=rv-&>p,n++);
p=(int*)calloc(n,sizeof(int));
count=(int)pow(2,n);
if((out-&>p-&>bf.idx=scan())==2)
{
combine();
sieve();
}
free(p);
}
}
void form_nl()
{
void get_not(),get_and(),connect_imp_gate(),get_or(),connect_out_gate(),get_eff_reset(),get_cp_rst(),get_nstring(),get_tsg(),get_op();
get_not();
get_and();
connect_imp_gate();
get_or();
connect_out_gate();
get_eff_reset();
get_cp_rst();
get_nstring(clock-&>name);
get_nstring(reset-&>name);
get_tsg();
get_op();
}
void display()
{
char *in_name(),*reg_str();
void first(),next();
strcpy(filectt,file);
strcat(filectt,"_netlist.txt");
fp=fopen(filectt,"w");
fprintf(fp,"`include "D_trigger.v"
");
first("module");
while(a[n]!=";") fputc(a[n++],fp);
fprintf(fp,";
");
for(first("input");a[n];next("input"))
{
while(a[n]!=";") fputc(a[n++],fp);
fprintf(fp,";
");
}
for(first("inout");a[n];next("inout"))
{
while(a[n]!=";") fputc(a[n++],fp);
fprintf(fp,";
");
}
for(first("output");a[n];next("output"))
{
while(a[n]!=";") fputc(a[n++],fp);
fprintf(fp,";
");
}
fprintf(fp,"
D_trigger
");
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
fprintf(fp,"D%d(",out-&>p-&>num);
if(out-&>p-&>clear_type==2) fprintf(fp,"1"b1,1"b1,");
else if(out-&>p-&>clear_type)
{
if(!out-&>p-&>clear_edge) fprintf(fp,"1"b1,%s,",reset-&>name);
else fprintf(fp,"1"b1,%s,",reset_not);
}
else
{
if(!out-&>p-&>clear_edge) fprintf(fp,"%s,1"b1,",reset-&>name);
else fprintf(fp,"%s,1"b1,",reset_not);
}
if(out-&>p-&>clock_edge) fprintf(fp,"%s,",clock-&>name);
else fprintf(fp,"%s,",clock_not);
if(out-&>p-&>idx==-1) fprintf(fp,"1"b%d,",out-&>p-&>dnum);
else if(!out-&>p-&>idx) fprintf(fp,"%s,",in_name(out-&>p-&>dnum));
else if(out-&>p-&>idx==1) fprintf(fp,"%s,",reg_str(out-&>p-&>dnum));
else if(out-&>p-&>idx==2) fprintf(fp,"qnout%d,",out-&>p-&>dnum);
else if(out-&>p-&>idx==3) fprintf(fp,"notout%d,",out-&>p-&>dnum);
else if(out-&>p-&>idx==4) fprintf(fp,"andout%d,",out-&>p-&>dnum);
else fprintf(fp,"orout%d,",out-&>p-&>dnum);
fprintf(fp,"%s,qnout%d",reg_str(out-&>p-&>num),out-&>p-&>num);
if(out-&>p-&>p!=NULL) fprintf(fp,"),
");
else fprintf(fp,");

");
}
fprintf(fp,"not
");
for(not=not_head;not-&>p!=NULL;not=not-&>p)
{
fprintf(fp,"not%d(notout%d,%s)",not-&>p-&>num,not-&>p-&>num,in_name(not-&>p-&>in));
if(not-&>p-&>p!=NULL) fprintf(fp,",
");
else fprintf(fp,";

");
}
fprintf(fp,"and
");
for(and=and_head;and-&>p!=NULL;and=and-&>p)
{
fprintf(fp,"and%d(andout%d",and-&>p-&>num,and-&>p-&>num);
for(iu=and-&>p-&>in_head;iu-&>p!=NULL;iu=iu-&>p)
fprintf(fp,",%s",in_name(iu-&>p-&>n));
for(ru=and-&>p-&>r_head;ru-&>p!=NULL;ru=ru-&>p)
fprintf(fp,",%s",reg_str(ru-&>p-&>n));
for(rnu=and-&>p-&>rn_head;rnu-&>p!=NULL;rnu=rnu-&>p)
fprintf(fp,",qnout%d",rnu-&>p-&>n);
for(nu=and-&>p-&>not_head;nu-&>p!=NULL;nu=nu-&>p)
fprintf(fp,",notout%d",nu-&>p-&>n);
if(and-&>p-&>p!=NULL) fprintf(fp,"),
");
else fprintf(fp,");

");
}
fprintf(fp,"or
");
for(or=or_head;or-&>p!=NULL;or=or-&>p)
{
fprintf(fp,"or%d(orout%d",or-&>p-&>num,or-&>p-&>num);
for(iu=or-&>p-&>in_head;iu-&>p!=NULL;iu=iu-&>p)
fprintf(fp,",%s",in_name(iu-&>p-&>n));
for(ru=or-&>p-&>r_head;ru-&>p!=NULL;ru=ru-&>p)
fprintf(fp,",%s",reg_str(ru-&>p-&>n));
for(rnu=or-&>p-&>rn_head;rnu-&>p!=NULL;rnu=rnu-&>p)
fprintf(fp,",qnout%d",rnu-&>p-&>n);
for(nu=or-&>p-&>not_head;nu-&>p!=NULL;nu=nu-&>p)
fprintf(fp,",notout%d",nu-&>p-&>n);
for(au=or-&>p-&>and_head;au-&>p!=NULL;au=au-&>p)
fprintf(fp,",andout%d",au-&>p-&>n);
if(or-&>p-&>p!=NULL) fprintf(fp,"),
");
else fprintf(fp,");

");
}
fprintf(fp,"bufif1
");
for(tsg=tsg_head;tsg-&>p!=NULL;tsg=tsg-&>p)
{
fprintf(fp,"TSG%d(%s,",tsg-&>p-&>num,tsg-&>p-&>out_name);
if(tsg-&>p-&>d_idx==-1) fprintf(fp,"1"b%d,",tsg-&>p-&>data);
else fprintf(fp,"%s,",reg_str(tsg-&>p-&>data));
fprintf(fp,"%s",reg_str(tsg-&>p-&>ena));
if(tsg-&>p-&>p!=NULL) fprintf(fp,"),
");
else fprintf(fp,");
");
}
fprintf(fp,"endmodule
");
fclose(fp);
printf("
%s的門級網表文件%s已在綜合器所在目錄生成,請查看

",filetxt,filectt);
}
void clear()
{
in=in_head;
out=out_head;
num=num_head;
pa=pa_head;
bl=bl_head;
gc=gc_head;
sv=sv_head;
not=not_head;
and=and_head;
or=or_head;
er=er_head;
tsg=tsg_head;
op=op_head;
in-&>p=NULL;
out-&>p=NULL;
num-&>p=NULL;
pa-&>p=NULL;
bl-&>p=NULL;
gc-&>p=NULL;
sv-&>p=NULL;
not-&>p=NULL;
and-&>p=NULL;
or-&>p=NULL;
er-&>p=NULL;
tsg-&>p=NULL;
op-&>p=NULL;
}
void input()
{
void sg(),pr();
sg("input ");
pr("input[");
}
void inout()
{
void sg(),pr();
sg("inout ");
pr("inout[");
}
void reg()
{
void sg(),pr();
sg("reg ");
pr("reg[");
}
void next_pa()
{
for(;a[n]!=","a[n]!=";";n++);
for(;a[n]&<"a"||a[n]&>"z";n++);
}
int get_range()
{
int i,cmp();
void range_type();
for(i=n;a[i]!=")";i++);
for(;a[i]&<"a"||a[i]&>"z";i++);
gc-&>p-&>start=i;
range_type(i);
return gc-&>p-&>end;
}
void get_else(int i,IN *in_p,int st)
{
int cmp();
void range_type();
gc=gc-&>p;
gc-&>p=calloc(1,sizeof(GC));
gc-&>p-&>in_p=in_p;
if(st==0) gc-&>p-&>st=1;
else gc-&>p-&>st=0;
for(i+=4;a[i]&<"a"||a[i]&>"z";i++);
gc-&>p-&>start=i;
range_type(i);
}
void edge(char *c)
{
int i,j,check_sv_cov();
char name[20];
void first(),next();
for(first(c);a[n];next(c))
{
for(i=n+strlen(c);a[i]&<"a"||a[i]&>"z";i++);
for(j=0;a[i]&>="a"a[i]&<="z";i++,j++) name[j]=a[i]; name[j]=0; if(!check_sv_cov(name)) { sv-&>p=calloc(1,sizeof(SV));
strcpy(sv-&>p-&>name,name);
sv=sv-&>p;
}
}
}
void dif_spe()
{
int seek_gc();
for(sv=sv_head;sv-&>p!=NULL;sv=sv-&>p)
if(seek_gc(sv-&>p-&>name))
{
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(in-&>p-&>name,sv-&>p-&>name)) reset=in-&>p;
}
else
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(in-&>p-&>name,sv-&>p-&>name)) clock=in-&>p;
}
void get_clock()
{
void find_al(),clock_edg();
find_al();
clock_edg("posedge ");
clock_edg("negedge ");
}
void ge_ee(int idx)
{
void first(),next(),gen_ee1(),gen_ee2();
for(first(ee_name);a[n];next(ee_name))
if(a[n+ee_name_len]=="~"||a[n+ee_name_len]&>="a"a[n+ee_name_len]&<="z") gen_ee1(idx); else gen_ee2(idx); } void sm_ee() { int i,cmp(); void first(),next(); for(first(ee_name);a[n];next(ee_name)) { ee2-&>p=calloc(1,sizeof(EE2));
ee2-&>p-&>addr=n;
for(pa=pa_head;pa-&>p!=NULL;pa=pa-&>p)
if(cmp(a[n+ee_name_len],pa-&>p-&>name))
{
for(i=0,val=pa-&>p-&>val_head;i&p,i++);
ee2-&>p-&>val=val-&>p-&>n;
}
ee2=ee2-&>p;
}
}
int check_sm()
{
char c[20];
int i,check_num();
void first(),next();
strcpy(c,out-&>p-&>name);
strcat(c,"&<="); for(first(c);a[n];next(c)) if(n&>=sm.startn&<=sm.end) return 1; if(check_num(out-&>p-&>name))
{
for(i=0;out-&>p-&>name[i]!="[";i++)
c[i]=out-&>p-&>name[i];
c[i]=0;
strcat(c,"&<="); for(first(c);a[n];next(c)) if(n&>=sm.startn&<=sm.end) return 1; } return 0; } void smcv() { int cmp(); for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(cmp(in-&>p-&>name,sm.name))
{
rv-&>p=calloc(1,sizeof(RV));
rv-&>p-&>in_p=in-&>p;
rv=rv-&>p;
}
}
void gcv()
{
void add_gcv();
for(ee1=out-&>p-&>ee1_head;ee1-&>p!=NULL;ee1=ee1-&>p)
{
n=ee1-&>p-&>addr;
add_gcv();
}
for(ee2=out-&>p-&>ee2_head;ee2-&>p!=NULL;ee2=ee2-&>p)
{
n=ee2-&>p-&>addr;
add_gcv();
}
}
void asnv()
{
int check_sv(),check_cov();
for(ee1=out-&>p-&>ee1_head;ee1-&>p!=NULL;ee1=ee1-&>p)
{
strcpy(v_name,ee1-&>p-&>in_p-&>name);
if(check_sv()) continue;
else if(check_cov()) continue;
else
{
rv-&>p=calloc(1,sizeof(RV));
rv-&>p-&>in_p=ee1-&>p-&>in_p;
rv=rv-&>p;
}
}
}
void sfv()
{
int check_cov();
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(in-&>p-&>name,out-&>p-&>name))
{
strcpy(v_name,in-&>p-&>name);
if(!check_cov())
{
rv-&>p=calloc(1,sizeof(RV));
rv-&>p-&>in_p=in-&>p;
rv=rv-&>p;
}
}
}
void ee1_de(int val)
{
void asn_de(),gc_de(),pa_de();
de-&>p=calloc(1,sizeof(DE));
de-&>p-&>st=val;
ive=de-&>p-&>ive_head;
asn_de(val);
gc_de();
pa_de();
de=de-&>p;
}
void ee2_de()
{
void gc_de(),pa_de();
de-&>p=calloc(1,sizeof(DE));
de-&>p-&>st=ee2-&>p-&>val;
ive=de-&>p-&>ive_head;
gc_de();
pa_de();
de=de-&>p;
}
void pre_asn()
{
int i,j,k,val;
for(rv=out-&>p-&>rv_head,i=0;rv-&>p!=NULL;rv=rv-&>p,i++)
if(!strcmp(rv-&>p-&>in_p-&>name,out-&>p-&>name)) break;
for(j=0;j&<=count-1;j++) { for(val=j,k=0;k&val=val%2;
}
}
void de_asn()
{
int i,check_de();
void get_bn();
for(i=0;i&<=count-1;i++) { get_bn(i); for(de=out-&>p-&>de_head;de-&>p!=NULL;de=de-&>p)
if(check_de()) {(tt+i)-&>val=de-&>p-&>st; break;}
}
}
int scan()
{
int i,zero=0,one=0;
for(i=0;i&val==0) zero=1;
if((tt+i)-&>val==1) one=1;
if(zeroone) return 2;
}
if(zero) return 0;
else return 1;
}
void combine()
{
int i;
void pickvar();
for(i=1;i&<=n;i++) { qua=i; ive1=calloc(i,sizeof(IVE)); pickvar(0,0,n-i); free(ive1); if(allcov) break; } } void sieve() { int rdd(); void erase(); for(imp=out-&>p-&>bf.imp_head;imp-&>p!=NULL;)
if(rdd(imp))
{
erase();
imp-&>p=imp-&>p-&>p;
}
else imp=imp-&>p;
}
void get_not()
{
int num,in_num(),check_reg(),check_not(),check_clock_not(),check_reset_not();
void add_not();
not=not_head;
for(count=0,out=out_head;out-&>p!=NULL;out=out-&>p)
for(imp=out-&>p-&>bf.imp_head;imp-&>p!=NULL;imp=imp-&>p)
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(!ive-&>p-&>st!check_reg()!check_not(num=in_num())) add_not(num);
if(check_clock_not()) add_not(clock-&>num);
if(check_reset_not()) add_not(reset-&>num);
}
void get_and()
{
int check_ive_num(),check_and();
void add_and();
and=and_head;
for(count=0,out=out_head;out-&>p!=NULL;out=out-&>p)
for(imp=out-&>p-&>bf.imp_head;imp-&>p!=NULL;imp=imp-&>p)
if(check_ive_num()&>1!check_and()) add_and();
}
void connect_imp_gate()
{
int check_ive_num(),check_reg(),reg_num(),in_num(),not_num(),and_num();
for(out=out_head;out-&>p!=NULL;out=out-&>p)
for(imp=out-&>p-&>bf.imp_head;imp-&>p!=NULL;imp=imp-&>p)
if(check_ive_num()==1)
{
ive=imp-&>p-&>ive_head;
if(!check_reg())
{
if(ive-&>p-&>st) imp-&>p-&>num=in_num();
else
{
imp-&>p-&>idx=3;
imp-&>p-&>num=not_num();
}
}
else
{
imp-&>p-&>num=reg_num();
if(ive-&>p-&>st) imp-&>p-&>idx=1;
else imp-&>p-&>idx=2;
}
}
else
{
imp-&>p-&>idx=4;
imp-&>p-&>num=and_num();
}
}
void get_or()
{
int num,imp_num();
for(count=0,or=or_head,out=out_head;out-&>p!=NULL;out=out-&>p)
if(imp_num()&>1)
{
or-&>p=calloc(1,sizeof(OR));
or-&>p-&>num=count++;
iu=or-&>p-&>in_head;
ru=or-&>p-&>r_head;
rnu=or-&>p-&>rn_head;
nu=or-&>p-&>not_head;
au=or-&>p-&>and_head;
for(imp=out-&>p-&>bf.imp_head;imp-&>p!=NULL;imp=imp-&>p)
{
num=imp-&>p-&>num;
if(!imp-&>p-&>idx)
{
iu-&>p=calloc(1,sizeof(NUM));
iu-&>p-&>n=num;
iu=iu-&>p;
}
else if(imp-&>p-&>idx==1)
{
ru-&>p=calloc(1,sizeof(NUM));
ru-&>p-&>n=num;
ru=ru-&>p;
}
else if(imp-&>p-&>idx==2)
{
rnu-&>p=calloc(1,sizeof(NUM));
rnu-&>p-&>n=num;
rnu=rnu-&>p;
}
else if(imp-&>p-&>idx==3)
{
nu-&>p=calloc(1,sizeof(NUM));
nu-&>p-&>n=num;
nu=nu-&>p;
}
else
{
au-&>p=calloc(1,sizeof(NUM));
au-&>p-&>n=num;
au=au-&>p;
}
}
out-&>p-&>idx=5;
out-&>p-&>dnum=or-&>p-&>num;
or=or-&>p;
}
}
void connect_out_gate()
{
int imp_num();
for(out=out_head;out-&>p!=NULL;out=out-&>p)
if(!imp_num())
{
out-&>p-&>idx=-1;
out-&>p-&>dnum=out-&>p-&>bf.idx;
}
else if(imp_num()==1)
{
imp=out-&>p-&>bf.imp_head;
out-&>p-&>idx=imp-&>p-&>idx;
out-&>p-&>dnum=imp-&>p-&>num;
}
}
void get_eff_reset()
{
int eff_reset();
er=er_head;
for(gc=gc_head;gc-&>p!=NULL;gc=gc-&>p)
if(!strcmp(gc-&>p-&>in_p-&>name,reset-&>name)eff_reset())
{
er-&>p=calloc(1,sizeof(ER));
er-&>p-&>st=gc-&>p-&>st;
er-&>p-&>start=gc-&>p-&>start;
er-&>p-&>end=gc-&>p-&>end;
er=er-&>p;
}
}
void get_cp_rst()
{
int addr;
for(out=out_head;out-&>p!=NULL;out=out-&>p)
{
out-&>p-&>clear_type=2;
ee1=out-&>p-&>ee1_head;
ee2=out-&>p-&>ee2_head;
addr=(ee1-&>p!=NULL)?ee1-&>p-&>addr:ee2-&>p-&>addr;
for(gc=gc_head;gc-&>p!=NULL;gc=gc-&>p)
if(!strcmp(gc-&>p-&>in_p-&>name,clock-&>name)addr&>=gc-&>p-&>startaddr&<=gc-&>p-&>end)
{
out-&>p-&>clock_edge=gc-&>p-&>st;
break;
}
for(;ee2-&>p!=NULL;ee2=ee2-&>p)
{
addr=ee2-&>p-&>addr;
for(er=er_head;er-&>p!=NULL;er=er-&>p)
if(addr&>=er-&>p-&>startaddr&<=er-&>p-&>end)
{
out-&>p-&>clear_edge=er-&>p-&>st;
out-&>p-&>clear_type=ee2-&>p-&>val;
goto s1;
}
}
s1:;
}
}
void get_nstring(char *name)
{
int i,val;
char temp[20]="notout",num[10],*in_name();
for(not=not_head;not-&>p!=NULL;not=not-&>p)
if(!strcmp(in_name(not-&>p-&>in),name))
{
if(!not-&>p-&>num) strcat(temp,"0");
else
{
for(val=not-&>p-&>num,i=0;val!=0;val/=10,i++)
num[i]=val%10+48;
num[i]=0;
strrev(num);
strcat(temp,num);
}
}
if(!strcmp(clock-&>name,name)) strcpy(clock_not,temp);
if(!strcmp(reset-&>name,name)) strcpy(reset_not,temp);
}
void get_tsg()
{
int i,j,tsg_reg_num();
void first(),next();
for(first("assign"),tsg=tsg_head,count=0;a[n];next("assign"),tsg=tsg-&>p,count++)
{
tsg-&>p=calloc(1,sizeof(TSG));
tsg-&>p-&>num=count;
for(i=n+strlen("assign"),j=0;a[i]!="=";i++)
if(a[i]&>="a"a[i]&<="z") { tsg-&>p-&>out_name[j]=a[i];
j++;
}
tsg-&>p-&>out_name[j]=0;
tsg-&>p-&>ena=tsg_reg_num(++i,"?");
while(a[i++]!="?");
if(a[i]=="0"||a[i]=="1")
{
tsg-&>p-&>d_idx=-1;
tsg-&>p-&>data=a[i]-48;
}
else tsg-&>p-&>data=tsg_reg_num(i,":");
}
}
void get_op()
{
int i;
char temp[20];
void first(),step();
op=op_head;
for(first("output "),n+=strlen("output ");a[n-1]!=";";step())
{
op-&>p=calloc(1,sizeof(OP));
for(i=0;a[n]!=","a[n]!=";";n++,i++)
temp[i]=a[n];
temp[i]=0;
strcpy(op-&>p-&>name,temp);
for(out=out_head;out-&>p!=NULL;out=out-&>p)
if(!strcmp(out-&>p-&>name,temp)) op-&>p-&>num=out-&>p-&>num;
op=op-&>p;
}
}
char *reg_str(int num)
{
int i;
char temp[10];
for(op=op_head;op-&>p!=NULL;op=op-&>p)
if(op-&>p-&>num==num) return op-&>p-&>name;
if(!num) strcpy(reg_string,"qout0");
else
{
for(i=0;num!=0;num/=10,i++)
temp[i]=num%10+48;
temp[i]=0;
strrev(temp);
strcpy(reg_string,"qout");
strcat(reg_string,temp);
}
return reg_string;
}
void sg(char *c)
{
int i,ind,cmp();
void step(),gens();
if(!strcmp(c,"reg ")) ind=0;
else ind=1;
for(i=0;a[i];i++)
if(cmp(a[i],c)) break;
for(n=i+strlen(c);a[n-1]!=";";step())
gens(ind);
}
void pr(char *c)
{
int i,ind,s,sum,len,cmp();
void step(),genp();
if(!strcmp(c,"reg[")) ind=0;
else ind=1;
for(i=0,len=strlen(c),num=num_head;!(a[i]=="
"a[i-1]=="
");i++)
if(cmp(a[i],c))
{
num-&>p=calloc(1,sizeof(NUM));
num=num-&>p;
num-&>n=i+len;
}
num-&>p=NULL;
for(num=num_head;num-&>p!=NULL;num=num-&>p)
{
for(n=num-&>p-&>n;a[n]!=":";n++);
for(n--,sum=0,s=1;a[n]!="[";n--,s*=10)
sum+=(a[n]-48)*s;
n1=sum;
for(;a[n]!="]";n++);
for(n--,sum=0,s=1;a[n]!=":";n--,s*=10)
sum+=(a[n]-48)*s;
n2=sum;
for(;a[n]!=" ";n++);
for(n++;a[n-1]!=";";step())
genp(ind);
}
num=num_head;
num-&>p=NULL;
}
void range_type(int i)
{
int cmp();
if(cmp(a[i],"begin"))
{
for(bl=bl_head;bl-&>p!=NULL;bl=bl-&>p)
if(bl-&>p-&>start==i) {gc-&>p-&>end=bl-&>p-&>end; break;}
}
else if(cmp(a[i],"case")) gc-&>p-&>end=sm.end;
else
{
for(;a[i]!=";";i++);
gc-&>p-&>end=i;
}
}
int check_sv_cov(char *name)
{
for(sv1=sv_head;sv1-&>p!=NULL;sv1=sv1-&>p)
if(!strcmp(sv1-&>p-&>name,name)) return 1;
return 0;
}
int seek_gc(char *c)
{
for(gc1=gc_head;gc1-&>p!=NULL;gc1=gc1-&>p)
if(!strcmp(gc1-&>p-&>in_p-&>name,c)) return 1;
return 0;
}
void find_al()
{
int i,cmp();
void first(),next();
al=al_head;
for(first("always");a[n];next("always"))
{
al-&>p=calloc(1,sizeof(BL));
al-&>p-&>start=n;
for(i=n+1;!(cmp(a[i],"always")||cmp(a[i],"endmodule"));i++);
al-&>p-&>end=i-1;
al=al-&>p;
}
}
void clock_edg(char *edg)
{
char c[20];
void first(),next();
strcpy(c,edg);
strcat(c,clock-&>name);
for(first(c);a[n];next(c))
{
gc-&>p=calloc(1,sizeof(GC));
for(al=al_head;al-&>p!=NULL;al=al-&>p)
if(n&>=al-&>p-&>startn&<=al-&>p-&>end)
{
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(in-&>p-&>name,clock-&>name)) gc-&>p-&>in_p=in-&>p;
gc-&>p-&>start=al-&>p-&>start;
gc-&>p-&>end=al-&>p-&>end;
}
if(!strcmp(edg,"posedge ")) gc-&>p-&>st=1;
else gc-&>p-&>st=0;
gc=gc-&>p;
}
}
void gen_ee1(int idx)
{
int i,j,cmp();
char name[20],ch[20];
ee1-&>p=calloc(1,sizeof(EE1));
ee1-&>p-&>addr=n;
if(idx==-1)
{
if(a[n+ee_name_len]=="~") {ee1-&>p-&>in_st=0; i=n+ee_name_len+1;}
else {ee1-&>p-&>in_st=1; i=n+ee_name_len;}
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(cmp(a[i],in-&>p-&>name)) ee1-&>p-&>in_p=in-&>p;
}
else
{
ee1-&>p-&>in_st=1;
for(i=n+ee_name_len,j=0;a[i]!=";";i++,j++)
name[j]=a[i];
name[j]="[";
name[j+1]=0;
if(!idx) {ch[0]="0"; ch[1]=0;}
else
{
for(j=0;idx!=0;idx/=10,j++)
ch[j]=idx%10+48;
ch[j]=0;
strrev(ch);
}
strcat(name,ch);
strcat(name,"]");
for(in=in_head;in-&>p!=NULL;in=in-&>p)
if(!strcmp(name,in-&>p-&>name)) ee1-&>p-&>in_p=in-&>p;
}
ee1=ee1-&>p;
}
void gen_ee2(int idx)
{
int i;
ee2-&>p=calloc(1,sizeof(EE2));
ee2-&>p-&>addr=n;
i=n+ee_name_len;
if(idx!=-1)
{
for(;a[i]!=";";i++);
for(i--;idx!=0;idx--,i--);
}
if(a[i]=="0") ee2-&>p-&>val=0;
else ee2-&>p-&>val=1;
ee2=ee2-&>p;
}
int check_num(char *c)
{
int i;
for(i=0;*(c+i);i++)
if(*(c+i)&>="0"*(c+i)&<="9") return 1; return 0; } void add_gcv() { int check_sv(),check_cov(); for(gc=gc_head;gc-&>p!=NULL;gc=gc-&>p)
{
strcpy(v_name,gc-&>p-&>in_p-&>name);
if(check_sv()) continue;
else if(check_cov()) continue;
else if(n&p-&>start||n&>gc-&>p-&>end) continue;
else
{
rv-&>p=calloc(1,sizeof(RV));
rv-&>p-&>in_p=gc-&>p-&>in_p;
rv=rv-&>p;
}
}
}
void asn_de(int val)
{
void get_ive();
strcpy(v_name,ee1-&>p-&>in_p-&>name);
if(ee1-&>p-&>in_st) st=val;
else st=!val;
get_ive();
}
void gc_de()
{
int check_sv();
void get_ive();
for(gc=gc_head;gc-&>p!=NULL;gc=gc-&>p)
if(n&>=gc-&>p-&>startn&<=gc-&>p-&>end)
{
strcpy(v_name,gc-&>p-&>in_p-&>name);
if(!check_sv())
{
st=gc-&>p-&>st;
get_ive();
}
}
}
void pa_de()
{
int i,cmp();
void get_ive();
for(pa=pa_head;pa-&>p!=NULL;pa=pa-&>p)
if(n&>=pa-&>p-&>startn&<=pa-&>p-&>end)
{
for(val=pa-&>p-&>val_head,i=0;val-&>p!=NULL;val=val-&>p,i++)
{
for(in=in_head,count=i;in-&>p!=NULL;in=in-&>p)
{
if(cmp(in-&>p-&>name,sm.name))
if(count==0) {strcpy(v_name,in-&>p-&>name); break;}
else count--;
}
st=val-&>p-&>n;
get_ive();
}
break;
}
}
int check_de()
{
if(de-&>p-&>ive_head.p==NULL) return 0;
else
{
for(ive=de-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(*(p+ive-&>p-&>num)!=ive-&>p-&>st) return 0;
return 1;
}
}
void pickvar(int idx,int start,int end)
{
int a;
void posneg();
for(a=start;a&<=end;a++) { (ive1+idx)-&>num=a;
if(end&p-&>ive_head,i=0;ive-&>p!=NULL;ive=ive-&>p,i++);
qua=i;
ive1=calloc(qua,sizeof(IVE));
for(ive=a-&>p-&>ive_head,i=0;ive-&>p!=NULL;ive=ive-&>p,i++)
{
(ive1+i)-&>num=ive-&>p-&>num;
(ive1+i)-&>st=ive-&>p-&>st;
}
for(i=0;i&idx) return 0;
return 1;
}
void erase()
{
int i,match();
for(i=0;i&idx--;
}
int check_not(int num)
{
for(not1=not_head;not1-&>p!=NULL;not1=not1-&>p)
if(not1-&>p-&>in==num) return 1;
return 0;
}
int check_clock_not()
{
for(gc=gc_head;gc-&>p!=NULL;gc=gc-&>p)
if(!strcmp(gc-&>p-&>in_p-&>name,clock-&>name)!gc-&>p-&>st) return 1;
return 0;
}
int check_reset_not()
{
for(er=er_head;er-&>p!=NULL;er=er-&>p)
if(er-&>p-&>st) return 1;
return 0;
}
void add_not(int num)
{
not-&>p=calloc(1,sizeof(NOT));
not-&>p-&>num=count++;
not-&>p-&>in=num;
not=not-&>p;
}
int check_ive_num()
{
int i;
for(ive=imp-&>p-&>ive_head,i=0;ive-&>p!=NULL;ive=ive-&>p,i++);
return i;
}
int check_and()
{
int check_and_num(),check_and_var();
for(and1=and_head;and1-&>p!=NULL;and1=and1-&>p)
if(check_and_num()check_and_var()) return 1;
return 0;
}
void add_and()
{
int check_reg(),in_num(),not_num(),reg_num();
and-&>p=calloc(1,sizeof(AND));
and-&>p-&>num=count++;
iu=and-&>p-&>in_head;
ru=and-&>p-&>r_head;
rnu=and-&>p-&>rn_head;
nu=and-&>p-&>not_head;
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(!check_reg())
{
if(ive-&>p-&>st)
{
iu-&>p=calloc(1,sizeof(NUM));
iu-&>p-&>n=in_num();
iu=iu-&>p;
}
else
{
nu-&>p=calloc(1,sizeof(NUM));
nu-&>p-&>n=not_num();
nu=nu-&>p;
}
}
else
{
if(ive-&>p-&>st)
{
ru-&>p=calloc(1,sizeof(NUM));
ru-&>p-&>n=reg_num();
ru=ru-&>p;
}
else
{
rnu-&>p=calloc(1,sizeof(NUM));
rnu-&>p-&>n=reg_num();
rnu=rnu-&>p;
}
}
and=and-&>p;
}
int and_num()
{
int check_and_num(),check_and_var();
for(and1=and_head;and1-&>p!=NULL;and1=and1-&>p)
if(check_and_num()check_and_var()) return and1-&>p-&>num;
return -1;
}
int imp_num()
{
int i;
for(imp=out-&>p-&>bf.imp_head,i=0;imp-&>p!=NULL;imp=imp-&>p,i++);
return i;
}
int eff_reset()
{
int al_state();
for(al=al_head;al-&>p!=NULL;al=al-&>p)
if(gc-&>p-&>start&>=al-&>p-&>startgc-&>p-&>end&<=al-&>p-&>endgc-&>p-&>st==al_state()) return 1;
return 0;
}
char *in_name(int num)
{
int i;
for(in=in_head,i=0;i&p,i++);
return in-&>p-&>name;
}
int tsg_reg_num(int start,char end)
{
int i,j;
char temp[20];
for(i=start,j=0;a[i]!=end;i++,j++)
temp[j]=a[i];
temp[j]=0;
for(out=out_head;out-&>p!=NULL;out=out-&>p)
if(!strcmp(out-&>p-&>name,temp)) return out-&>p-&>num;
return -1;
}
void step()
{
int i;
for(i=0;a[n+i]!=","a[n+i]!=";";i++);
n+=i+1;
}
void gens(int ind)
{
void getin(),getout();
if(ind==1)
{
getin();
in=in-&>p;
}
else
{
getin();
in=in-&>p;
getout();
out=out-&>p;
}
}
void genp(int ind)
{
int i,j,p,q;
char t,lett[20];
void getin(),getout();
lett[0]="[";
for(i=n2;i&<=n1;i++) { if(i==0) { lett[1]="0"; lett[2]="]"; lett[3]=0; } else { for(p=i,j=1;p!=0;p/=10,j++) lett[j]=p%10+48; for(p=1,q=j-1;p&p-&>name,lett);
in=in-&>p;
}
else
{
getin();
strcat(in-&>p-&>name,lett);
in=in-&>p;
getout();
strcat(out-&>p-&>name,lett);
out=out-&>p;
}
}
}
void first(char* c)
{
int cmp();
for(n=0;!cmp(a[n],c)a[n];n++);
}
void next(char *c)
{
int cmp();
for(n++;!cmp(a[n],c)a[n];n++);
}
int check_sv()
{
for(sv=sv_head;sv-&>p!=NULL;sv=sv-&>p)
if(!strcmp(sv-&>p-&>name,v_name)) return 1;
return 0;
}
int check_cov()
{
for(rv1=out-&>p-&>rv_head;rv1-&>p!=NULL;rv1=rv1-&>p)
if(!strcmp(rv1-&>p-&>in_p-&>name,v_name)) return 1;
return 0;
}
void get_ive()
{
ive-&>p=calloc(1,sizeof(IVE));
for(rv=out-&>p-&>rv_head,count=0;rv-&>p!=NULL;rv=rv-&>p,count++)
if(!strcmp(rv-&>p-&>in_p-&>name,v_name)) break;
ive-&>p-&>num=count;
ive-&>p-&>st=st;
ive=ive-&>p;
}
void posneg()
{
int i,j,val,fil(),uncov(),cov();
void obt();
for(i=0;i&<(int)pow(2,qua);i++) { for(val=i,j=0;j&st=val%2;
if(fil()uncov()) obt();
if(allcov=cov()) break;
}
}
int check_and_num()
{
int i1,i2,i3,i4,j1,j2,j3,j4,check_reg();
for(iu=and1-&>p-&>in_head,i1=0;iu-&>p!=NULL;iu=iu-&>p,i1++);
for(ru=and1-&>p-&>r_head,i2=0;ru-&>p!=NULL;ru=ru-&>p,i2++);
for(rnu=and1-&>p-&>rn_head,i3=0;rnu-&>p!=NULL;rnu=rnu-&>p,i3++);
for(nu=and1-&>p-&>not_head,i4=0;nu-&>p!=NULL;nu=nu-&>p,i4++);
for(ive=imp-&>p-&>ive_head,j1=j2=j3=j4=0;ive-&>p!=NULL;ive=ive-&>p)
{
if(!check_reg())
{
if(ive-&>p-&>st) j1++;
else j4++;
}
else
{
if(ive-&>p-&>st) j2++;
else j3++;
}
}
if(i1==j1i2==j2i3==j3i4==j4) return 1;
else return 0;
}
int check_and_var()
{
int check_in_st(),check_reg_st(),check_regn_st(),check_not_st();
for(iu=and1-&>p-&>in_head;iu-&>p!=NULL;iu=iu-&>p)
if(!check_in_st()) return 0;
for(ru=and1-&>p-&>r_head;ru-&>p!=NULL;ru=ru-&>p)
if(!check_reg_st()) return 0;
for(rnu=and1-&>p-&>rn_head;rnu-&>p!=NULL;rnu=rnu-&>p)
if(!check_regn_st()) return 0;
for(nu=and1-&>p-&>not_head;nu-&>p!=NULL;nu=nu-&>p)
if(!check_not_st()) return 0;
return 1;
}
int al_state()
{
int cmp();
char temp[30];
strcpy(temp,"posedge ");
strcat(temp,reset-&>name);
for(n=al-&>p-&>start;a[n]!=")";n++)
if(cmp(a[n],temp)) return 1;
return 0;
}
void getin()
{
int i,j;
in-&>p=calloc(1,sizeof(IN));
in-&>p-&>num=count_in++;
for(i=n,j=0;a[i]!=","a[i]!=";";i++,j++)
in-&>p-&>name[j]=a[i];
}
void getout()
{
int i,j;
out-&>p=calloc(1,sizeof(OUT));
out-&>p-&>num=count_out++;
for(i=n,j=0;a[i]!=","a[i]!=";";i++,j++)
out-&>p-&>name[j]=a[i];
}
int cmp(char *m,char *t)
{
int i;
for(i=0;*(t+i);i++)
if(*(m+i)!=*(t+i)) return 0;
return 1;
}
int fil()
{
int i,match();
for(i=0;i&val) return 0;
return 1;
}
int uncov()
{
int i,match();
for(i=0;i&idx) return 1;
return 0;
}
void obt()
{
int i,match();
for(i=0;i&idx++;
imp-&>p=calloc(1,sizeof(IMP));
ive=imp-&>p-&>ive_head;
for(i=0;i&p=calloc(1,sizeof(IVE));
ive-&>p-&>num=(ive1+i)-&>num;
ive-&>p-&>st=(ive1+i)-&>st;
ive=ive-&>p;
}
imp=imp-&>p;
}
int cov()
{
int i;
for(i=0;i&val!(tt+i)-&>idx) return 0;
return 1;
}
int check_in_st()
{
int check_reg(),in_num();
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(!check_reg()ive-&>p-&>stin_num()==iu-&>p-&>n) return 1;
return 0;
}
int check_reg_st()
{
int check_reg(),reg_num();
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(check_reg()ive-&>p-&>streg_num()==ru-&>p-&>n) return 1;
return 0;
}
int check_regn_st()
{
int check_reg(),reg_num();
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(check_reg()!ive-&>p-&>streg_num()==rnu-&>p-&>n) return 1;
return 0;
}
int check_not_st()
{
int check_reg(),not_num();
for(ive=imp-&>p-&>ive_head;ive-&>p!=NULL;ive=ive-&>p)
if(!check_reg()!ive-&>p-&>stnot_num()==nu-&>p-&>n) return 1;
return 0;
}
int match(int val)
{
int i;
void get_bn();
get_bn(val);
for(i=0;i&num)!=(ive1+i)-&>st) return 0;
return 1;
}
int check_reg()
{
int i;
for(rv=out-&>p-&>rv_head,i=0;i&p-&>num;rv=rv-&>p,i++);
for(out1=out_head;out1-&>p!=NULL;out1=out1-&>p)
if(!strcmp(out1-&>p-&>name,rv-&>p-&>in_p-&>name)) return 1;
return 0;
}
int reg_num()
{
int i;
for(rv=out-&>p-&>rv_head,i=0;i&p-&>num;rv=rv-&>p,i++);
for(out1=out_head;out1-&>p!=NULL;out1=out1-&>p)
if(!strcmp(out1-&>p-&>name,rv-&>p-&>in_p-&>name)) return out1-&>p-&>num;
return -1;
}
int not_num()
{
int num,in_num();
num=in_num();
for(not=not_head;not-&>p!=NULL;not=not-&>p)
if(not-&>p-&>in==num) return not-&>p-&>num;
return -1;
}
void get_bn(int val)
{
int i;
for(i=0;i&p-&>rv_head,i=0;i&p-&>num;rv=rv-&>p,i++);
return rv-&>p-&>in_p-&>num;
}


netlist (相信你這裡說的是SPICE netlist) 和RTL可不一樣。

模擬的netlist是放到模擬器里跑,模擬器的方法其實很公開,SPICE關注的是解矩陣。

RTL方面,我認為你問的應該是形式驗證模擬,而不是綜合或跑時序之類的。

驗證的是邏輯,用C或是Verilog其實原理都一樣,只不過是換成HDL之後加入了更多面向電路方向的細節,但是在實質上都是邏輯運算。這時候VCS、NC或modelSim就相當於一個解釋/編譯器,最後還是編譯成C代碼,然後在CPU上跑。


看你要幹什麼,問題太寬泛。在不同的工具比如placer, route裡面會用到很多不同的數據結構。工具的數據結構和電路靜態存儲的數據結構又是不一樣的。


數字IC建模一般在行為級建模吧,C++或systemC就能描述了,普通的C編譯軟體就行了吧。我是用FPGA做數字IC,ASIC不太清楚。做FPGA到RTL級,就純粹是各種寄存器模塊了。考慮更多的是面積和關鍵路徑,和模型結構關係就不大了。我也剛做這方面,也不是特別清楚。


借地一問,有沒有相關書籍推薦?


如果只是要做類似modelsim模擬的話,(我猜)那跟普通編譯器甚至解釋器一樣,把verilog當成一門普通的編程語言解釋就行了。

如果要繼續,比如要燒到FPGA上或者做成ASIC,數字電路的RTL描述首先被綜合成門級的描述,然後是physical design的過程,通過布局(place)、布線(routing)生成版圖級的描述。

如果是模擬電路,以spice為例,模擬時底層大概是各種矩陣然後不斷解方程。

題主似乎是復旦微電子的,關於數字電路的EDA flow,可以上一下俞軍老師的ASIC選修課,或者王伶俐老師的FPGA課,如果想要了解具體的布局、布線演算法,楊帆老師開有physical design的研究生課程。如果想了解模擬電路的EDA演算法,曾璇老師有模擬電路分析的研究生課程。


推薦閱讀:

兩個電勢不等的電源並聯會怎樣?
為什麼歷史上發現電子後,沒有規定電子流動的方向為電流的方向,而仍然用「正電荷」的概念來解釋呢?
為什麼石墨烯處理器能夠達到1THz?
非平衡電橋中間的導線為什麼有電流?
如何理解穩恆電路中電阻兩端的電壓?

TAG:半導體 | 電路 | 晶元集成電路 | EDA |