3 Star 21 Fork 10

yhp / iverilog_module

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
run 9.09 KB
一键复制 编辑 原始数据 按行查看 历史
yhp 提交于 2021-05-28 23:04 . 脚本修正
#!/bin/bash
#仿真脚本
#by yunahp 2020/5/31
####################### 仿真脚本 #######################
#该脚本用于仿真模块,仿真时讲所需文件拷贝到sim文件夹,避免路径问题导致仿真失败。
# clear
DIR=`dirname $0` #获取当前路径
exdir=$(cat db.dat)
cd $exdir
#echo $exdir
exdir=$(pwd)
#echo $exdir
exdir=${exdir##*/}
#echo $exdir
cd - &> /dev/null #回到上次目录
if [ "$1" = "-unhide" ];then #显示所有隐藏的工程文件夹
if [ ! -d module ];then
echo -e "\033[36mERROR:不存在module 路径\033[0m"
exit 1
fi
cd module
dir=$(ls -al | awk '/^d/ {print $NF}')
for i in $dir
do
if [ "$i" = "." ] ;then
continue
fi
if [ "$i" = ".." ] ;then
continue
fi
dst=${i//./}
if [ "$i" != "$dst" ];then
mv $i $dst
fi
done
echo -e "\033[36mINFO:已经显示隐藏的文件夹,请查看 module 路径下!\033[0m"
exit 0
fi
if [ "$1" = "-hide" ];then #隐藏所有除正在调试的工程文件夹
if [ ! -d module ];then
echo -e "\033[36mERROR:不存在module 路径\033[0m"
exit 1
fi
cd module
dir=$(ls -l | awk '/^d/ {print $NF}')
for i in $dir
do
if [ "$i" = "." ] ;then
continue
fi
if [ "$i" = ".." ] ;then
continue
fi
if [ "$i" = "$exdir" ] ;then
continue
fi
dst=".$i"
mv $i $dst
done
echo -e "\033[36mINFO:已经隐藏所有除正在调试的工程文件夹,请查看 module 路径下!\033[0m"
exit 0
fi
if [ "$1" = "-i" ];then #在指定路径生成testbech模板
clear
if [ ! -d $2 ];then
echo -e "\033[36mINFO:工程路径不存在!将创建工程!\033[0m"
mkdir -p $2
fi
cd $2
if [ -f tb.v ];then
echo "ERROR:初始化失败,路径 $2 中已存在tb.v文件!"
exit 0
fi
cat <<EOF >tb.v
\`timescale 1ns / 1ps
module tb ;
reg clk,rst;
//生成始时钟
parameter NCLK = 4;
initial begin
clk=0;
forever clk=#(NCLK/2) ~clk;
end
/****************** 开始 ADD module inst ******************/
/****************** 结束 END module inst ******************/
initial begin
\$dumpfile("wave.lxt2");
\$dumpvars(0, tb); //dumpvars(深度, 实例化模块1,实例化模块2,.....)
end
initial begin
rst = 1;
#(NCLK) rst=0;
#(NCLK) rst=1; //复位信号
repeat(100) @(posedge clk)begin
end
\$display("运行结束!");
\$dumpflush;
\$finish;
\$stop;
end
endmodule
EOF
echo -e "\033[36mINFO:已在$2下生成tb.v文件!\033[30"
exit 0
fi
#=============================================================================
if [ "$1" = "-clk" ];then #在指定路径生成任意分频器模板
clear
if [ ! -d $2 ];then
echo -e "\033[36mINFO:工程路径不存在!将创建工程!\033[0m"
mkdir -p $2
fi
cd $2
if [ -f divide.v ];then
echo "ERROR:生成失败,路径 $2 中已存在divide.v文件!"
exit 0
fi
cat<<EOF >divide.v
\`timescale 1ns / 1ps
// ********************************************************************
// FileName : divide.v
// Author :hpy
// Email :yuan_hp@qq.com
// Date :2020年06月18日
// Description :任意整数时钟分频
// --------------------------------------------------------------------
module divide#(
parameter WIDTH = 3, //计数器的位数,计数的最大值为 2**WIDTH-1
parameter N = 3 //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出
) (
input clk,
input rst_n,
output clkout
);
reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p为上升沿触发时的计数器,cnt_n为下降沿触发时的计数器
reg clk_p,clk_n; //clk_p为上升沿触发时分频时钟,clk_n为下降沿触发时分频时钟
//上升沿触发时计数器的控制
always @ (posedge clk or negedge rst_n ) //posedge和negedge是verilog表示信号上升沿和下降沿
//当clk上升沿来临或者rst_n变低的时候执行一次always里的语句
begin
if(!rst_n)
cnt_p<=0;
else if (cnt_p==(N-1))
cnt_p<=0;
else cnt_p<=cnt_p+1; //计数器一直计数,当计数到N-1的时候清零,这是一个模N的计数器
end
//上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%;如果N为偶数得到的时钟占空比为50%
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_p<=0;
else if (cnt_p<(N>>1)) //N>>1表示右移一位,相当于除以2去掉余数
clk_p<=0;
else
clk_p<=1; //得到的分频时钟正周期比负周期多一个clk时钟
end
//下降沿触发时计数器的控制
always @ (negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_n<=0;
else if (cnt_n==(N-1))
cnt_n<=0;
else cnt_n<=cnt_n+1;
end
//下降沿触发的分频时钟输出,和clk_p相差半个时钟
always @ (negedge clk)
begin
if(!rst_n)
clk_n<=0;
else if (cnt_n<(N>>1))
clk_n<=0;
else
clk_n<=1; //得到的分频时钟正周期比负周期多一个clk时钟
end
assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p; //条件判断表达式
//当N=1时,直接输出clk
//当N为偶数也就是N的最低位为0,N(0)=0,输出clk_p
//当N为奇数也就是N最低位为1,N(0)=1,输出clk_p&clk_n。正周期多所以是相与
endmodule
EOF
echo "INFO:成功在路径$2下生成divide.v文件!"
exit 0
fi
#==============================================================================
if [ "$1" == "-clean" ] #当仿真参数是 -clear时删除sim文件夹下所有文件,包括仿真数据
then
rm -rf ./sim/* #清空sim文件夹下的内容
echo "note:clean success!"
exit 0
fi
if [ "$1" == "-f" ] #运行单文件
then
if [ -f $2 ];then
clear
echo -e "\033[36m运行单文件verilog,如用于处理文件的文件,当前运行的是:$2\033[0m"
iverilog $2
vvp a.out
echo
rm -f a.out
else
echo "ERROR:文件$2不存在!"
fi
exit 0
fi
if [ "$1" == "-h" ] #帮助
then
echo " Usage: run [para] <string>"
echo " run -d dir 仿真dir目录"
echo " run -i dir 在指定文件夹生成testbech模板,不存在路径则先创建路径"
echo " run -f file 运行单.v文件分析"
echo " run 仿真上次仿真的目录"
echo " run -h 显示帮助"
echo " run -r 刷新仿真数据,不在重新开启新的gtkwave"
echo " run -clk dir 在指定文件夹生成任意分频器的模板divide.v,不存在路径则先创建路径"
echo " run -hide 隐藏除了正在调试所有工程文件夹(module路径下的文件夹)"
echo " run -unhide 显示所有隐藏的工程文件夹(module路径下的)"
exit 0
fi
if [ "$1" == "-d" ] #指定要仿真的文件夹开始仿真
then
DST_DIR=$2
if [ ! -d $DST_DIR ];then
echo "ERROR:仿真目录不能存足,执行参数应为 run -d 需要仿真的目录"
exit 1
fi
stat=$(echo $(ls $DST_DIR | grep '.v'))
if [ "$stat" = "" ];then
echo "ERROR:文件路径第一层目录下没有任何可用于仿真的文件!"
exit 1
fi
echo "$DST_DIR" > db.dat #保存上次仿真路径
fi
DIR=$(cat db.dat)
if [ ! -d $DIR ];then
echo "ERROR:仿真的目录不存在,执行参数应为 (run -d 需要仿真的目录) 以更新仿真数据记录"
exit 1
fi
if [ -f "$DIR/run.sh" ] ; then #如果指定目录存在run.sh脚本,就执行run.sh脚本
./$DIR/run.sh
exit 0
fi
echo -e "\033[36mINFO: 当前仿真的目录为 $DIR \033[0m"
#检测到说明文件,显示说明文件中带有title:后面的内容做为功能说明
README=$DIR/readme.md
README=${README//\/\//\/}
if [ -f "$README" ];then
nt=`awk -F':' '/title:/{print $2}' $README`
echo -e "\033[36mINFO: 项目说明(^_^) $nt \033[0m"
fi
rm -rf ./sim/* #清空sim文件夹下的内容
#为当前项目生成tags文件
ctags -R $DIR
#拷贝文件项目文件(.v)到仿真目录sim
src=$(find $DIR -name "*.v")
cp $src ./sim/
#cp $DIR/*.v ./sim/
#ln -s $DIR/*.v ./sim/
#进入仿真文件所在的文件夹
cd sim
PARA=$(ls *.v)
iverilog -o wave $PARA #综合verilog代码
vvp -n wave -lxt2 #仿真
##下面根据运行脚本时传入的参数进行选择运行
if [ "$1" == "-r" ] #当仿真参数是 -r时只更新数据,不在新开启gtkwave
then
echo ""
echo "note:rebuild success!"
echo -e "\033[36mplease reload wave in gtkwave!\033[0m"
echo ""
exit 0
fi
gtkwave wave.lxt2 &> /dev/null & #显示波形
echo
exit 0
Verilog
1
https://gitee.com/yuan_hp/iverilog_module.git
git@gitee.com:yuan_hp/iverilog_module.git
yuan_hp
iverilog_module
iverilog_module
master

搜索帮助