南大数字逻辑与计算机组成课程实验四计时器与时钟 思路与代码参考

Verilog

top.v

module top (
  input clk,
  input rst,
  input pause,
  output reg [3:0] num0, // 个位
  output reg [3:0] num1, // 十位
  output reg [6:0] seg0, // 个位 数码管
  output reg [6:0] seg1  // 十位 数码管
);
  reg [31:0] count;
  always @(posedge clk) begin
    if(rst) begin count <= 0; num0 <= 4'd0; num1 <= 4'd0;end // 初始化和重置
    else if(!pause)begin
      count <= (count >= 500000? 32'b0 :  count + 1);  // 改变时钟的周期
      if(count == 32'd0) begin
        if(num0 == 4'd9)begin  // 个位为9进1
          if(num1 == 4'd9)begin num0 <= 4'd0;num1 <= 4'd0; end // 99时重置
          else begin
            num0 <= 4'd0;
            num1 <= num1 + 4'd1;
          end
        end
        else begin num0 <= num0 + 4'd1;end
      end
    end
  end

seg my_seg(
  .clk(clk),
  .rst(rst),
  .num0(num0),
  .num1(num1),
  .seg0(seg0),
  .seg1(seg1)
  );
endmodule

别问,问就是疯狂if else 😦。

seg.v

module seg (
    input clk,
    input rst,
    input [3:0] num0,
    input [3:0] num1,
    output reg [6:0] seg0,
    output reg [6:0] seg1
);
wire [6:0] segs [9:0];
assign segs[0] = 7'b0000001;  // 0为亮 1为熄
assign segs[1] = 7'b1001111;
assign segs[2] = 7'b0010010;
assign segs[3] = 7'b0000110;
assign segs[4] = 7'b1001100;
assign segs[5] = 7'b0100100;
assign segs[6] = 7'b0100000;
assign segs[7] = 7'b0001111;
assign segs[8] = 7'b0000000;
assign segs[9] = 7'b0001100;
always@(posedge clk)begin
    case (num0)
        4'd0:seg0 = segs[0];
        4'd1:seg0 = segs[1];
        4'd2:seg0 = segs[2];
        4'd3:seg0 = segs[3];
        4'd4:seg0 = segs[4];
        4'd5:seg0 = segs[5];
        4'd6:seg0 = segs[6];
        4'd7:seg0 = segs[7];
        4'd8:seg0 = segs[8];
        4'd9:seg0 = segs[9];
        default: seg0 = segs[0];
    endcase
        case (num1)
        4'd0:seg1 = segs[0];
        4'd1:seg1 = segs[1];
        4'd2:seg1 = segs[2];
        4'd3:seg1 = segs[3];
        4'd4:seg1 = segs[4];
        4'd5:seg1 = segs[5];
        4'd6:seg1 = segs[6];
        4'd7:seg1 = segs[7];
        4'd8:seg1 = segs[8];
        4'd9:seg1 = segs[9];
        default: seg1 = segs[0];
    endcase
end
endmodule

sim_main.cpp

cpp文件的说明见文章

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<nvboard.h>

#include"Vtop.h"
#include"verilated.h"
#include"verilated_vcd_c.h"

void nvboard_bind_all_pins(Vtop* top);

int main(int argc, char** argv) {
    VerilatedContext* contextp = new VerilatedContext;
    contextp->traceEverOn(true);
    contextp->commandArgs(argc, argv);

    Vtop* top = new Vtop{contextp};

    nvboard_bind_all_pins(top);
    nvboard_init();
    VerilatedVcdC* m_trace = new VerilatedVcdC;
    top->trace(m_trace, 99);
    m_trace->open("wave.vcd");
    
    top->clk = 0;
    int n = 3;
    top->rst = 1;
    m_trace->dump(contextp->time());
    //----原reset函数---- 进行信号初始化
    while (n -- > 0)
    {
    	contextp->timeInc(1); // 推进仿真时间
    	top->clk = !top->clk;
    	top->eval(); // 模型更新
    	m_trace->dump(contextp->time()); // 记录波形
    }
    //----原reset函数----
    top->rst = 0;
    top->pause = 0;
    
    while (!contextp->gotFinish()) {
	nvboard_update();
        contextp->timeInc(1);
        top->clk = !top->clk;
        top->eval();
        m_trace->dump(contextp->time());
    }
    m_trace->close();
    delete top;
    delete contextp;
    return 0;
}

引脚绑定

top=top

rst SW0
pause SW1
seg0 (SEG0A, SEG0B, SEG0C, SEG0D, SEG0E, SEG0F, SEG0G)
seg1 (SEG1A, SEG1B, SEG1C, SEG1D, SEG1E, SEG1F, SEG1G)

sw0用于清零重置,sw1用于暂停 。
NVBoard用于查看00-99时,建议关闭波形记录,不然磁盘会爆炸的。

拓展的电子时钟我当初没做,等我更到NPC再回来写吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

long0_o

可以吗!真的可以吗!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值