题目要求:串口发送模块
-
明确功能 输入输出+功能描述
clk,rst_n,
-
画功能波形图
-
确定计数器结构
cnt0表示每bit多少clk
cnt1表示第几位
初值,加一条件和结束条件见代码
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt0 <= 0;
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = flag==1 ;
assign end_cnt0 = add_cnt0 && cnt0==5208-1 ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt1 <= 0;
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 10-1
- 其他信号 初值+确定变化点
变化点要精确到某个clk
flag: din_vld到来变1,数据发送结束变0,其他时候保持。
dout: 初值为1,flag=1期间,clk1计数一次发送一位
注意:
dout的起始点若是add_cnt1,则在cnt1计数0结束时才会开始,与时序不符。
给某个变量赋值,比如dout,在cnt0=0赋值一次,其他时候保持就行;不用在整个cnt0=0~5207期间一直赋值;或者说,和状态机一样遵循变化条件精确到一个clk
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
flag <= 0;
else if(din_vld)
flag <= 1;
else if(end_cnt1)
flag <= 0;
end
parameter din = 8'b11010110;
assign d_r = {1'b1,din,1'b0};
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
dout <= 1;
else if(add_cnt0&&cnt0==0) //这是提取某个计数值的标准格式
dout <= d_r[cnt1];
//else dout <= 1; 这句会造成在某个cnt1的cnt0=1~5207时,dout本来应该保持,结果变1
end