liudingding 发表于 2017-8-1 12:18:04

谁给我编写这段verilog代码我出一百元饭钱

我只会AHDL语言,但是编写的程序有致命缺陷,没人指点不知错在哪里,没法继续下去,只好用其它语言重写,无奈verilog看不懂,因此找人编写个样板,注释越多越好,我照葫芦画瓢,完成我的设计,内容如下:

一个非门构成晶振电路,该晶振电路频时钟三分频得时钟A。时钟A输出。

一个计数器F,时钟为A,在第十、二十、三十、四十时钟时输出脉冲B、C、D、E,计数到100时输出脉冲P与时钟A相或(这时计数器时钟等于P、A相或一直为高电平)终止计数,计数器各位输出,B、C、D、E输出。

另一个计数器G,时钟为C、D、E合并后的信号,B为清零信号。

两个八位锁存器L、N,八位锁存器的锁存时钟是51单片机低八位通过锁存器锁存(这个锁存器的输入用下面某个三态端口输入)的总共十六位的地址总线为某个数据时,L、N输出数据相加,相加结果与G输出通过控制信号M选择某一路输出。

两个八位三态端口J、K,数据从一个端口输入,另一个端口输出,两个端口的三态控制信号分别为H、I。

zxq6 发表于 2017-8-1 12:24:50

会ahdl,就用ahdl呗

偏偏倒倒 发表于 2017-8-1 12:34:40

不复杂,不过,如果是FPGA的话,建议统一时钟,不要用多时钟的方式。
ASIC的话,另说了。

RAMILE 发表于 2017-8-1 12:45:10

画图多方便,quartuesII有原理图输入

chensi007 发表于 2017-8-1 12:49:37

顶楼上。原理图多方便。

90999 发表于 2017-8-1 12:53:52

你画个时序图处理把,很多地方讲不明白,比如 “ 计数到100时输出脉冲P与时钟A相或” 。

liudingding 发表于 2017-8-1 12:58:20

90999 发表于 2017-8-1 12:53
你画个时序图处理把,很多地方讲不明白,比如 “ 计数到100时输出脉冲P与时钟A相或” 。 ...

就是说脉冲P与时钟A合并作为计数器的时钟,P为高电平了,时钟就一直为高电平了,就停止计数了

90999 发表于 2017-8-1 13:12:04

liudingding 发表于 2017-8-1 12:58
就是说脉冲P与时钟A合并作为计数器的时钟,P为高电平了,时钟就一直为高电平了,就停止计数了 ...

那你P作为A的开关不就好了。

到这为止我大概明白上面怎么写,但是



两个八位锁存器L、N,八位锁存器的锁存时钟是51单片机低八位通过锁存器锁存(这个锁存器的输入用下面某个三态端口输入)的总共十六位的地址总线为某个数据时,L、N输出数据相加,相加结果与G输出通过控制信号M选择某一路输出。

两个八位三态端口J、K,数据从一个端口输入,另一个端口输出,两个端口的三态控制信号分别为H、I。

这两个又这么理解?




你把思路理清楚,不用给我100你也写得出来了。

dykwai1 发表于 2017-8-1 13:25:37

应该学过C语言吧,verilog和C语法很像的,学起来不难

liudingding 发表于 2017-8-1 13:34:03

本帖最后由 liudingding 于 2017-8-1 15:24 编辑

90999 发表于 2017-8-1 13:12
那你P作为A的开关不就好了。

到这为止我大概明白上面怎么写,但是

好比51单片机系统有个573锁存器,锁存低八位地址,这里的锁存器的锁存时钟信号是这51系统十六位地址为某一数据如FFFF,当这个地址产生锁存时钟,好比用一个片选信号作为锁存时钟,好比接RAM,在FFFF地址锁存一个数据,在FFFE地址锁存一个数据,这两个数据作为锁存器锁存的数据处理,这里有两组锁存器,一组锁存低八位地址数据,另一组锁存特定地址的数据

两个双向端囗就是CPU和RAM之间有一个CPLD,CPLD分别两个三态端口与CPU和RAM交换数据

liudingding 发表于 2017-8-1 15:32:34

谁帮我写一下呀?

90999 发表于 2017-8-1 15:46:12

本帖最后由 90999 于 2017-8-1 17:01 编辑

liudingding 发表于 2017-8-1 13:34
好比51单片机系统有个573锁存器,锁存低八位地址,这里的锁存器的锁存时钟信号是这51系统十六位地址为某一 ...

两个八位锁存器L、N,八位锁存器的锁存时钟是51单片机低八位通过锁存器锁存(这个锁存器的输入用下面某个三态端口输入)的总共十六位的地址总线为某个数据时,L、N输出数据相加,相加结果与G输出通过控制信号M选择某一路输出。

好比51单片机系统有个573锁存器,锁存低八位地址,这里的锁存器的锁存时钟信号是这51系统十六位地址为某一数据如FFFF,当这个地址产生锁存时钟,好比用一个片选信号作为锁存时钟,好比接RAM,在FFFF地址锁存一个数据,在FFFE地址锁存一个数据,这两个数据作为锁存器锁存的数据处理,这里有两组锁存器,一组锁存低八位地址数据,另一组锁存特定地址的数据



这个我还是不明白,是下面的意思么?

P0=0x20   ->L(锁存) \
                      (+) =0x40->M(触发)-> G=0x30
P1=0x10   ->N(锁存) /

还是


P0=0x20   ->L(锁存) \
                      {L,N} =0x2010 ->M(触发)-> G=0x2010
P1=0x10   ->N(锁存) /







两个八位三态端口J、K,数据从一个端口输入,另一个端口输出,两个端口的三态控制信号分别为H、I。

X Y Z
H Z H
L Z H
H H L
L L L

这个是这样吧。

liudingding 发表于 2017-8-1 16:01:26

本帖最后由 liudingding 于 2017-8-1 16:10 编辑

低八位数据   74HC573(用CPLD实现573的功能) 锁存\
                                                                            51系统的十六位地址数据如FFFF译码后的片选信号作为锁存时钟    +74HC573,后面这个573是L或N,一路包含两片573,一个地址锁存器,另一个数据锁存器
高八位直通                                                         /
以上这么两路,结果相加\
                                     这两路通过M选择一路输出
另一个计数器                /

两个八位三态端口,J、K都为高电平,三态门输出三态状态,J低电平K高电平,三态门连接CPU数据端的那个三态门高阻,连接RAM的那个三态们输出CPU输入到高阻三态门的数据,J高电平K低电平,连接RAM的三态门高阻,连接CPU的那个三态门输出RAM输入到三态门的数据

90999 发表于 2017-8-1 16:13:17

本帖最后由 90999 于 2017-8-2 11:43 编辑


assign XO =!XI;
assign CLK_IN = XO; //XI XO 反相器接晶体


//三分频
reg q1,q2;
wire q3;

always @(posedge CLK_IN) //CLK_IN 是时钟
case (q1)
0:q1<=1;
1:q1<=2;
2:q1<=0;
default:q1<=0;
endcase
       
always @(negedge RXCK)
case (q2)
0:q2<=1;
1:q2<=2;
2:q2<=0;
default:q2<=0;
endcase       

assign q3=q1|q2;//q3=CLK_IN/3q3 = CLK_IN的1/3




//
assign A= (1&&P)||(CLK_IN&&(!P));

reg n100;
reg B,C,D,E,P;

always @ (posedgeA or negedge RST)      //RST ϽµÑظ´Î»£¬·ñÔòP=1»á¹Ø±ÕʱÖÓA
begin
        if(!RST)
                begin
                n100=0;
                end
        else
                begin
                B=0;C=0;D=0;E=0;P=0;
                if(n100==9)B=1;
                if(n100==19) C=1;
                if(n100==29) D=1;
                if(n100==39) E=1;
                if(n100==99) P=1;
                end
end










reg m255
always @( posedge ( (C||D)||(E||B) )        //任意CDEB都触发
begin

if(B)                        //B触发清零
begin
m255=0;
end
else
begin
m255=m255+1;          //其他加一
end

end



       


wire ADD_INA;                        //地址A 低8位
reg ADD_OUTA;

always @(posedge LATCH_ADD)        //地址锁存
begin
ADD_OUTA = ADD_INA;
end

assign ADD_A = {ADD_H8A,ADD_INA}; //地址A= 高8位低8位


wire DATA_INA;        //数据A输入
reg DATA_OUTA;        //数据A输出

always @(posedge LATCH_DATA) //数据锁存
begin
DATA_OUTA= DATA_INA;
end




wire ADD_INB;
reg ADD_OUTB;

always @(posedge LATCH_ADD)
begin
ADD_OUTB= ADD_INB;
end

assign ADD_B = {ADD_H8A,ADD_OUTB};



wire DATA_INB;
reg DATA_OUTB;

always @(posedge LatchDATA)
begin
DATA_OUTB = DATA_INB;
end


assign DATA_OUT = DATA_OUTA + DATA_OUTB; //数据 = 数据A+数据B









inout JI, KI, JO, KO;
wire H,I;

assign JI        =(        H?        JO                        :8'bZZZZZZZZ        );                //74HC245
assign JO        =(        H?        8'bZZZZZZZZ        :JI                        );


assign KI        =(        I?        KO                        :8'bZZZZZZZZ        );
assign KO        =(        I?        8'bZZZZZZZZ        :KI                        );




90999 发表于 2017-8-1 16:25:14

本帖最后由 90999 于 2017-8-1 16:26 编辑

低八位数据   74HC573(用CPLD实现573的功能) 锁存\(1)
                                                                            51系统的十六位地址数据如FFFF译码后的片选信号作为锁存时钟    +74HC573,后面这个573是L或N,一路包含两片573,一个地址锁存器,另一个数据锁存器
高八位直通                                                         /
以上这么两路,结果相加\(2)
                                     这两路通过M选择一路输出
另一个计数器                /




老实讲我还是看不懂什么意思。

reg L8_IN,L8_O;       

always @( posedgeLATCH_LOW_8)         //(1)
begin
L8_O=L8_IN;
end

wire X16;


//(2)

//assign X16 = {H8_I,L8_O};         //H8=0x10,L8=0x20, X16=0x1020
// assign X16 = H8_I+L8_O;         //H8=0x10,L8=0x20, X16=0x30

liudingding 发表于 2017-8-1 16:29:43

本帖最后由 liudingding 于 2017-8-1 16:38 编辑

90999 发表于 2017-8-1 16:25
低八位数据   74HC573(用CPLD实现573的功能) 锁存\(1)
                                                ...

要这个
//assign X16 = {H8_I,L8_O}; //
H8=0x10,L8=0x20, X16=0x1020   , X16=0x1020译码后的片选信号作为锁存时钟锁存地址为0x1020时的数据,这就是L或N


非门做上了吗?


always @( posedge ( (C||D)||(E||B) )
begin
//???????????
end
复制代码
这个完善一下吧

jlhgold 发表于 2017-8-1 16:29:52

楼主如果能想明白逻辑 说不定直接原理图也就出来了{:lol:}

fuze2009 发表于 2017-8-1 16:32:58

哈哈,100块的红包,诱人啊~

90999 发表于 2017-8-1 16:43:53

51的外置RAM , 应该是 地址,数据,锁存,读写 这些IO。 你要用单P0来处理,那么就要用一个573来锁存地址
那么就是P0=ADDRESS, 地址573锁存, P0=Z/DATA,读写=READ/WRITE , 锁存RAM, 然后就能操作RAM了。

双向三态口,这个我没用过,也不知道能不能用,你自己试试了。

inout X;Y;
input oe;
assign X=oe?Y:Z;
assign Y=oe?Z:X;

90999 发表于 2017-8-1 16:45:08

jlhgold 发表于 2017-8-1 16:29
楼主如果能想明白逻辑 说不定直接原理图也就出来了

{:lol:}我都说过了,他自己都表达不清楚。

90999 发表于 2017-8-1 16:58:38

fuze2009 发表于 2017-8-1 16:32
哈哈,100块的红包,诱人啊~

他给钱,我就是收,他不给钱,我就是雷锋。

我要再多他也没有,纯粹给论坛丢点范例,顺便弄点零花钱。






90999 发表于 2017-8-1 17:14:15

liudingding 发表于 2017-8-1 16:29
要这个
//assign X16 = {H8_I,L8_O}; //
H8=0x10,L8=0x20, X16=0x1020   , X16=0x1020译码后的片选信 ...

非门是 "!" ,取反是"~"



always @( posedge ( (C||D)||(E||B) )
begin
//???????????
end


这个我都不明白你实现什么?
随便画的SB的时序图

A(0)-(A9)-A(19)-A(29)-A(39)-A(99)-H
B000010000000000000000000000000
C000000000100000000000000000000
D000000000000001000000000000000
E000000000000000000010000000000
P000000000000000000000000001111



计数器G要实现什么样的图形,你要干什么,一会说CDE合并做时钟,B复位,一下说要和H8L8做片选?
B001000000000000100   
C000000001000000000
D000000000100000000   
E000000000010000000
变成
S0000000001111111000
S1000000000111111000
S2000000000011111000

这样?

那你就写

if(B)
begin
S=0;
end
if(C) S=1;
if(D) S=1;
if(E) S=1;


90999 发表于 2017-8-1 17:17:03

你要单片机选地址,然后把计数器CDE状态存进去,然后过段时间读出来?

liudingding 发表于 2017-8-1 19:26:29

本帖最后由 liudingding 于 2017-8-1 19:33 编辑

90999 发表于 2017-8-1 17:17
你要单片机选地址,然后把计数器CDE状态存进去,然后过段时间读出来?

画了个图

90999 发表于 2017-8-1 20:32:32

liudingding 发表于 2017-8-1 19:26
画了个图

CDE 来信号加1,B来信号清零就简单了。


reg m255
always @( posedge ( (C||D)||(E||B) )
begin

if(B)
begin
m255=0;
end
else
begin
m255=m255+1;
end


end

90999 发表于 2017-8-1 20:38:35


wire L8_IN;
reg L8_O;      

always @( posedgeLATCH_LOW_8)         //(1)
begin
L8_O=L8_IN;
end

wire X16;


//(2)

assign X16 = {H8_I,L8_O};         //H8=0x10,L8=0x20, X16=0x1020
// assign X16 = H8_I+L8_O;         //H8=0x10,L8=0x20, X16=0x30



wire DATA_IN;
reg DATA_OUT;
always @(posedge LatchDATA)
begin
DATA_OUT = DATA_IN;
end

//assign DATA_OUT_3 = DATA_OUT_1 + DATA_OUT_2;





自己修改组合一下应该差不多了。

liudingding 发表于 2017-8-1 21:33:36

90999 发表于 2017-8-1 20:38
自己修改组合一下应该差不多了。

款给你打过去了,请查收。
最后麻烦你照一楼要求把各部分合成一个文件就行了。
我把我程序中需要的几个不同部分画入这个图,因此从该图看不出干什么。
第二个计数器是在第一个计数器基础上进行计数,达到效果是脉冲CDE到来后输出不同状态,B进行清零,可以连续输出一连串的周期性脉冲信号。

90999 发表于 2017-8-1 22:35:31

liudingding 发表于 2017-8-1 21:33
款给你打过去了,请查收。
最后麻烦你照一楼要求把各部分合成一个文件就行了。
我把我程序中需要的几个不 ...

去14楼看。

liudingding 发表于 2017-8-2 07:24:33

好,我慢慢整一下看看

liudingding 发表于 2017-8-2 10:29:39

本帖最后由 liudingding 于 2017-8-2 11:16 编辑

90999 发表于 2017-8-1 22:35
去14楼看。

程序上机过了一遍,除了第一个计数器外都通过了,你把第一个计数器的程序编译通过贴出来吧,这一关过了就没疑问了,贴出编译通过的程序交易结束

90999 发表于 2017-8-2 11:43:54

本帖最后由 90999 于 2017-8-2 11:46 编辑

liudingding 发表于 2017-8-2 10:29
程序上机过了一遍,除了第一个计数器外都通过了,你把第一个计数器的程序编译通过贴出来吧,这一关过了就 ...


assign A= (1&&P)||(CLK_IN&&(!P));

reg n100;
reg B,C,D,E,P;

always @ (posedgeA or negedge RST)      //RST ϽµÑظ´Î»£¬·ñÔòP=1»á¹Ø±ÕʱÖÓA
begin
        if(!RST)
                begin
                n100=0;
                end
        else
                begin
                B=0;C=0;D=0;E=0;P=0;
                if(n100==9)B=1;
                if(n100==19) C=1;
                if(n100==29) D=1;
                if(n100==39) E=1;
                if(n100==99) P=1;
                end
end


稍微漏点东西你自己改不好么?


liudingding 发表于 2017-8-2 12:06:07

这就没问题了
页: [1]
查看完整版本: 谁给我编写这段verilog代码我出一百元饭钱