fpga 8段4位数码管verilator模拟

8段4位数码管verilator模拟
在这里插入图片描述

seg.v

module seg(
  input wire clk,
  input wire rst_n,
  output wire[7:0] SEG,
  output wire[3:0] SEL
);

reg[7:0]  digit[0:15] = '{8'h3f, 8'h06, 8'h5b, 8'h4f, 8'h66, 8'h6d, 8'h7d,8'h07,
                          8'h7f,8'h6f, 8'h77, 8'h7c, 8'h39, 8'h5e, 8'h79, 8'h71};

reg[31:0] cnt = 32'h0000000000;

always @(posedge clk or negedge rst_n) begin
  if (!rst_n)
    cnt <= 32'h00000000;
  else
   cnt <= cnt + 1;
end

reg[1:0] shift;

assign shift = cnt[16:15];

assign SEL = 4'b0001 << shift;
assign SEG = digit[4'(cnt[31:20]>>shift*4)];

endmodule

转接
seg_adaptor.v

module seg_adaptor(
  input wire clk,
  input wire[7:0] SEG,
  input wire[3:0] SEL
);
import "DPI-C"  function void  print(byte seg, byte sel);
reg[3:0] state = 4'b0001 ;

always @(posedge clk)
  if (state != SEL) begin
    print(byte'(SEG),byte'(SEL));
    state <= SEL;
  end

endmodule

tb
top.v

module top;
wire[7:0] seg;
wire[3:0] sel;
reg clk = 1'b0;
reg rst_n = 1'b0;

initial begin
  #10 rst_n = 1'b1;
  forever #1  clk = ~clk;
end

seg  seg1(.clk(clk),
          .rst_n(rst_n),
          .SEG(seg),
          .SEL(sel));

seg_adaptor  adaptor1(.clk(clk),
                      .SEG(seg),
                      .SEL(sel));

endmodule

print.h

#ifdef __cplusplus
extern "C"{
#endif

void print(char seg, char sel);

#ifdef __cplusplus
}
#endif

print.c

#define DIGIT_NUM 4
#include 
#include 
#include 
#include "svdpi.h"
#include "print.h"

static inline void prt(unsigned char data,int bit,char c) {
  if(data&(1<<bit)) putchar(c);
  else putchar(' ');
}

static inline void printu(unsigned char data, int b1, int b2, int b3)
{
  prt(data,b1,'|') ;
  prt(data,b2,'_') ;
  prt(data,b3,'|') ;

}

void printd(unsigned char data){
  printf("\x1b[C");  //前进一格
  prt(data,0,'_');
  printf("\x1b[B\x1b[2D"); //下移一格后退两格
  printu(data,5,6,1);
  printf("\x1b[B\x1b[3D");  //下移一格后退三格
  printu(data,4,3,2);
  prt(data,7,'.');
}

void print(char sg, char sel) {
  unsigned char  seg = (unsigned char ) sg;
  static int init = 0;
  if (init == 0) {
    printf("\n\n\n");
    init = 1;
    printf("\x1b[?25l");  //隐藏光标
  }
  unsigned char c = sel;
  for(int i = 7; i >= 0; i--)
    if(sel&(1<<i)) {
      printf("\x1b[2A\x1b[%dG",(DIGIT_NUM-i-1)*4+1); //上移两行定位
      printd(seg);
    }
  fflush(stdout);
}

Makefile

.PHONY:clean

VERILATOR = verilator

OUTDIR=out
VERILATOR_FLAGS = -Wall  -top top -Mdir $(OUTDIR) -cc -binary -build -j 2

default: run

run: print.c top.v  seg.v seg_adaptor.v
        $(VERILATOR) $(VERILATOR_FLAGS) $^
        ./$(OUTDIR)/Vtop

rc:  #restore cursor visibility
        @echo -ne "\x1b[?25h"

clean:
        -rm -rf $(OUTDIR)
make

ctrl c 退出后光标会隐藏
恢复光标显示

 make rc  

已上传github

git clone https://github.com/yses/fpgasim

你可能感兴趣的:(fpga开发)