我的芯片之路2
我的芯片之路2
上回说到
捋一捋信号,一共sha_clk, sha_reset_b, sha_wdata, sha_addr, sha_rw_b, sha_ipen, sha_rdata, pre几个
sha_clk, 时钟
sha_reset_b复位
sha_wdata写入的8位数据,常量
,sha_addr, 写入数据的地址
sha_rw_b, 读写线控制信号
sha_ipen, 使能信号
sha_rdata,读出的7位数据/唯一输出
pre,32转8的一个控制信号(这个信号的做法有待商榷,不过不讨论了)
现在进度是需要明确结构,或者说架构?
l 需要明确东西是怎样工作的
需要明确的是,如果用FPGA替代sha_iptop_tb,我需要做的首先应该是明确结构图


既然是从FPGA中综合实现,那应该只有sha_clk,reset和output sha_rdata三个信号。开机即启动
l 用状态机FSM实现tb内容
对原tb分析,状态机初步状态分配如下
版本shasha9_20160812
always@(posedge sha_clk)
if(sha_reset_b == 1’b0)
begin
//current_state= S1;
current_state=S0;
end
else//测试卡了许久,需要+else这里
case(current_state)
S0:begin
sign0=1’b0;//重置延时标记
sign1=1’b0;
sign2=1’b0;
sha_ipen=1’b0;
sha_rw_b=1’b1;
sha_addr=5’b00000;
sha_wdata=8’b0;
pre=2’b00;
delaystart=1’b0;
delay=0;
startS1=1’b0;
sign0=1’b0;
sign1=1’b0;
sign2=1’b0;
current_state=S1;
end
S1:begin//start
if(startS1==1’b0)
begin
delaystart =1’b1;
delay =16’h0040;
if(delaystop==1)//完成延时
begin
delaystart=1’b0;
delay=1;
startS1=1’b1;
sign0=1’b1;
end
end
//信号sign0,对应 #500 sha_ipen=1’b1;
else if(sign0==1’b1)
begin
if(reuse==1)
begin
delaystart=1’b1;
delay=24;
monitor3_reg =1;
if(delaystop==1)//完成延时
begin
delaystart=1’b0;
sha_ipen=1’b1;
delay=2;
sign1=1’b1;
sign0=1’b0;
end
end
end
//信号sign1,对应#500
else if(sign1==1’b1)
begin
if(reuse==1)
begin
delaystart=1’b1;
delay=26;
if(delaystop==1)//完成延时
begin
delaystart=1’b0;
delay=3;
sign1=1’b0;
current_state=S2;
end
end
end
end
S2:begin
monitor1_reg=1;
W32be(SHACTRL,32’h0000000a);
//#8000;
begin
delaystart=1’b1;
delay=350;
if(delaystop==1)//完成延时
begin
delaystart=1’b0;
// s2ign0=1’b1;
end
end
if(s2ign0 == 1’b1)
begin
read(SHACTRL);
read(SHADO0);
read(SHADO1);
read(SHADO2);
read(SHADO3);
read(SHADO4);
read(SHADO5);
read(SHADO6);
read(SHADO7);
current_state =S3 ;
end
end
S3:begin
W32(SHADI0,32’h61626364); //S3状态,W32数据
W32(SHADI1,32’h62636465);
W32(SHADI2,32’h63646566);
W32(SHADI3,32’h64656667);//read(SHADI3);
W32(SHADI4,32’h65666768);//read(SHADI4);
W32(SHADI5,32’h66676869);//read(SHADI5);
W32(SHADI6,32’h6768696a);//read(SHADI6);
W32(SHADI7,32’h68696a6b);//read(SHADI7);
W32(SHADI8,32’h696a6b6c);//read(SHADI8);
W32(SHADI9,32’h6a6b6c6d);//read(SHADI9);
W32(SHADIA,32’h6b6c6d6e);//read(SHADIA);
W32(SHADIB,32’h6c6d6e6f);//read(SHADIB);
W32(SHADIC,32’h6d6e6f70);//read(SHADIC);
W32(SHADID,32’h6e6f7071);//read(SHADID);
W32(SHADIE,32’h80000000);//read(SHADIE);
W32(SHADIF,32’h00000000);//read(SHADIF);
read(SHADI0);
read(SHADI1);
read(SHADI2);
read(SHADI3);
read(SHADI4);
read(SHADI5);
read(SHADI6);
read(SHADI7);
read(SHADI8);
read(SHADI9);
read(SHADIA);
read(SHADIB);
read(SHADIC);
read(SHADID);
read(SHADIE);
read(SHADIF);
current_state =S4;
end
S4:begin
read(SHACTRL);
W32(SHACTRL,32’h00000009);
read(SHACTRL);
current_state =S5;
end
S5:begin
//#14000;
begin
delaystart=1’b1;
delay=560;
if(delaystop==1)//完成延时
begin
delaystart=1’b0;
end
end
if(s5ign0 == 1’b1)
begin
read(SHADO0);
read(SHADO1);
read(SHADO2);
read(SHADO3);
read(SHADO4);
read(SHADO5);
read(SHADO6);
read(SHADO7);
read(SHACTRL);
current_state =S0;
end
需要意识到的问题是,
ü 代码中标示部分的else必须加上。要不然过不去编译,一直是一堆
** Error: F:/Software/About Career/[test]shasha5_20160811/sha_state_tb.v(147): near “=”: syntax error, unexpected ‘=’, expecting IDENTIFIER or TYPE_IDENTIFIER
卡了好久,我对modelsim编译器的运作不是很清楚,是否像C++那样if之后没有大括号就只运行一句话。而且,硬件貌似不是那么顺句而为的
注意if,else要配套
ü 这个版本我意识到不能用for(i=0;i<100;i++);这种做延时了。我重制了sha_counter.v
//这个计数器是可以用的。。。可以被大家借鉴。。。个人认为比网上其他的计数器靠谱得多。。。
module counter(clk,rst,start,delay,stop,reuse);
input clk,rst;
input start;
input [15:0] delay;//delayæ°æ®
// input delay;
output wire stop;//stop=1时,本次计时结束
output wire reuse;//resure=1时,可以开始下一次计数周期
reg [15:0] counter=16’h0;
reg stop_reg=1’b0;
reg reuse_reg=1’b0;
reg [1:0] state=2’b00;
assign stop = stop_reg;
assign reuse = reuse_reg;
always @ (posedge clk or rst)
begin
if (rst==1’b0)//
begin
counter <= 16’h0;
stop_reg <= 1’b0;
reuse_reg<= 1’b1;
state <= 2’b00;
end
else
case(state)
2’b00:
begin
stop_reg <=1’b0;
reuse_reg<=1’b1;
if(start == 1’b1)
begin
state = 2’b01;
reuse_reg=1’b0;
end
else
begin
stop_reg <=1’b0;//
reuse_reg<=1’b1;
end
end
2’b01:
begin
reuse_reg<=1’b0;
counter <= counter + 1;
if(counter==delay)
begin
stop_reg <= 1’b1;
state <= 2’b10;
counter <=16’h0;
end
end
2’b10:
begin
// state <= 2’b11;
state <=2’b00;
// reuse_reg=1’b1;
end
endcase
end
endmodule
工作信号大概如图

ü Reuse信号没有被用到(后面多次用到别处,最终还是没用)。Stop和reuse的波形关系如上图。具体的调用请见后文,这篇主代码并不完善。
l 分析原sha_iptop_tb信号的定义
reg [7:0] sha_wdata ; //tb文件中与所test的module的输入端口相连接的变量定义为reg
reg sha_rw_b ;
reg sha_clk ;
reg [4:0] sha_addr ;
reg [1:0] pre ;
wire [7:0] sha_rdata ; //tb文件中与所test的module的与输出端口相连的定义为wire
可以reg sha_rdata_reg;
assign sha_rdata = sha_rdata_reg;
reg sha_ipen ;
reg sha_reset_b ;
ü 一个module里面的output一般定义为wire,在module内需要对这个output的wire修改,可以定义reg xxx_reg;assign xxx(wire)=xxx_reg;,对这个xxx_reg进行操作,相当于对output wire进行操作
ü Output一般定义为wire类型,但wire不一定定义为output,只是视情况而定,wire是瞬时改变值

下期开始将write和read两项工作也用FSM状态机化,及期间的一些思考及问题。
*******************
补上期应该有的前期调研整理,该芯片的一些控制字和算法流程


——————————–
微博@georgeuser,一枚很可能要搞硬件的喵控的专业记录日记。
记录我所走过的路,愿我的分享能予人一些借鉴,也愿我某日再回头时能再拾起细节。