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 <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#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