某电FPGA作业二:FPGA实现求出一个32bit字中两个相邻1之间最大间隙的电路

写在前面:

个人留个笔记,如果有必要请联系qq(见csdn账号),我会删除
顺便一提,每学期的题目会有小改动,直接抄被发现直接挂科
顺顺便一提,今年有叫做了全部作业和设计结果挂科不服的,老师直接点出来抄就没反驳了,谁知道抄没呢,嘻嘻

任务要求:

设计一个能求出一个32bit字中两个相邻1之间最大间隙的电路。给出HDL设计及testbench描述,综合后的时序仿真结果及分析说明。
系统化分为状态机控制器和数据通路,信号的接口关系可参考下图(a)所示:
在这里插入图片描述
数据通路包括一个位计数器(k)、一个存储寄存器(tmp)、一个间隙寄存器(Gap)。
控制器产生的控制信号包括:
flush_tmp:清空tmp寄存器
incr_tmp: 增加tmp寄存器
store_tmp:用tmp加载Gap
incr_k: 增加k计数器
根据ASDM图,将过程设计为4个条件变化的状态,其中,s_0->s_1条件为输入位为1,s_1-》s_2的条件为输入为0,s_2->s_done条件为输入为1或31位(输入信息结束)。S_2-》s_1条件为输入为1且不为31。
图中部分状态转移的 1 应该改为0,15应该变为31.
在这里插入图片描述

代码和解释如下:

module Main(
    input clk,
    input rst,
    input [0:31] Data,
    output [0:4] gap
);
reg [0:4] temp,k,gap;
reg flush_tmp,store_tmp,incr_k,incr_tmp;
parameter s_0=0,s_1=1,s_2=2,s_done = 3;
reg [1:0] state,next_state;
wire CurrentD=Data[k];
always @(posedge clk,posedge rst)
    if(rst)
        state<=s_0;
    else
        state<=next_state;
    
always@(k or CurrentD or state)begin
//!!!
// 为了防止上次判断影响,每次进入判断先归零判断信号量为不变化
    next_state = state;
    incr_tmp = 0;
    incr_k = 0;
    store_tmp = 0;
    flush_tmp = 0;
    
    case(state)
    // 首先判断起始的0位置再计数
    s_0:
        // 如果最后一位,直接返回,是0就0把没用了
        if(k==31)
            next_state = s_done;
        else
            // 如果当前的指向数据为1,进入计数阶段
            if(CurrentD)begin
                next_state = s_1;
                incr_k = 1;
            end
            else begin
                next_state = s_0;
                incr_k = 1;
            end
    s_1:
        if(k==31)
            next_state = s_done;
        else if(!CurrentD) begin 
        //刚进入这个阶段说明上一个是1
        // 此时发现一个0,说明有空隙,开始计数并进入第三阶段--等待下一个1
            next_state = s_2;
            incr_tmp = 1;
            incr_k = 1;
        end
        else begin
        // 否则说明跟着一个0,之间没有空袭,将目前的0视作开始重新进入s_1
            next_state = s_1;
            incr_k = 1;
        end
    s_2:
        if(k==31)
        // 如果最后一位刚好给一堆s_2累计的1结尾了,且刚好大于最大gap,就把temp存入gap输出
            if(CurrentD)
                if(temp>gap)begin 
                    store_tmp = 1;
                    next_state = s_done;
                end
                // 否则直接结尾
                else begin
                    next_state = s_done;
                end
            // 如果最后一位没结尾
            else begin
                next_state = s_done;
            end
        else begin
        // 如果不是最后一位
        // 如果下一位是0,到此终止排序,比较内容
            if(CurrentD) 
                if(gap<temp) begin
                // 如果为 1,到此终结长度,存入gap,并返回s_1等待下一个1
                    store_tmp = 1;
                    next_state = s_1;
                    incr_k = 1;
                    flush_tmp = 1;
                end
                else begin
                    // 保持状态2,找另一个0
                    flush_tmp = 1;
                    incr_k = 1;
                end
            else begin
                // 如果下一位是1,累加长度
                incr_tmp = 1;
                incr_k = 1;
                ///
                end
            end
        
    s_done:
        begin
        // 结束后状态归零,等待下一次输入
            next_state = s_0;
            incr_k = 0;
        end
    default:
        // 对于未知的状态,状态归零
        next_state = s_0;
    endcase
end

// 监测程序,每一个时钟往后一位 or 转入 gap
always@(posedge clk,posedge rst)
begin 
    if(rst)begin
        k<=0;
        temp<=0;
        gap<=0;
    end
    else begin 
        if(flush_tmp)
            temp <=0;
        if(store_tmp)
            gap<=temp;
        if(incr_k)
            k <=k+1;
        if(incr_tmp)
            temp <= temp + 1;
    end
end

endmodule

得到综合电路如下:
在这里插入图片描述

仿真激励

文件如下:

module testbench();
    // 输入:clk,rst和校验内容
    reg clk,rst;
    reg [0:31]  data_in;
    // 输出 结果
    wire [0:4] gap;
    //程序调用
    Main u1(
        .clk(clk),
        .rst(rst),
        .Data(data_in),
        .gap(gap)
    );
    
    always #5 clk= ~clk;
    
    initial begin 
        clk = 0;
        rst = 1;
        data_in = 0;
        
        #100
        rst = 0; 
        data_in = 32'b1000_0000_0000_0000_0100_0000_0000_1010;

        #350
        rst = 1;
        #30
        rst = 0;
        data_in = 32'b1010_1000_0000_0001_0000_0000_0000_0001;
    end
endmodule

得到时序仿真如下所示:
在这里插入图片描述如图,rst复位结束后,随着第一个clk posedge信号变化进入s_1且temp累计计数,第二位为0,进入s_2累加temp,直到读取第17位,此位置为1,是所求的另一端,因为不是第32位,存入gap输出且复位temp,之后状态返回s_1,循环之前操作,最后(读取32位时)输出为正确结果(输出为16进制)

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值