(二)vhdl如何转换转换verilog?(人肉翻译—保姆教学版)

1、前言

    上一章大体上已经完成了顶层模块的转换,若后期编译有语法上或者其他报错再继续进行修改和注释。    继续上一章的转换,咱们进入到工程的第一个模块。

2、进入转换

        端口定义和赋值按照之前的步骤直接转换,这里就不在做过多的赘述,直接上图

端口定义:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity CLK_RST_CTRL is
    port (

    	OSC_CLK				: in	std_logic; 
		FPGA_RST			: in	std_logic;
		SYS_CLK 			: out	std_logic;
module rst_ctrl(
    input       osc_clk				,
    input       fpga_rst			,
    output      sys_clk				,

赋值

	signal 	s_osc_clk				: std_logic;     
	signal 	s_osc_rst				: std_logic;     
	signal 	s_dcm_rst				: std_logic;
    reg  	s_osc_clk				;     
	reg  	s_osc_rst				;     
	reg  	s_dcm_rst				;

接下来又遇到例化模块,不同之前的,这里多出另一个语法generic和vhdl的进制转换,这里就先介绍vhdl转verilog的进制转化,后面在讲generic的转换。

    U_SRL16_0 : SRL16E
       	generic map (
       	    init					=> x"0000"
       	)
       	port map (
       	    D						=> FPGA_RST				,
       	    CLK						=> s_osc_clk			,
       	    Q						=> s_osc_rst			,
       	    CE 						=> '1'					,
       	    A3						=> '1'					,
       	    A2						=> '1'					,
       	    A1						=> '1'					,
       	    A0						=> '1'
       	    );

这里用到了移位寄存器,就给大家普及一下Xilinx 的SRL16E ,它本质就是一个移位寄存器,顾名思义就是一个16位的移位寄存器。它这个移位寄存器可以是固定的、静态的长度,移位寄存器的长度可以从 1位到 16位不等,由下面公式决定:
                                                                长度 =(8 x A3)+(4 x A2)+(2 x A1)+A0+1
如果 A3,A2,A1,A0都是 0(0000),移位寄存器的长度就是 1位长;如果它们 都是 1(1111),移位寄存器的长度就是 16位长。这里就简单介绍,想要了解更多用法可以自行搜索。

回到主题,开始对vhdl的进制数转换为veriong的进制数,在转换之前也得先了解vhdl的数位字符串

数位字符串(位矢量)代表的是二进制,8进制,16进制的数组,长度为等值的二进制数位数

B:二进制,       O:八进制,   X:十六进制,

例如:    
B’1_1110_1111         表示二进制数数组,位矢数组长度是9
X’27        表示十六进制数数组,位矢数组长度是8
O’AD0       表示八进制数数组,位矢数组长度是6

结合verilog的用法上述几个字符串可以这样换:

B’1_1110_1111         verilog表示为   9'b1_1110_1111
X’27                          
verilog表示为    8'h27       
O’AD0                       verilog表示为    6'OAD0

上述vhdl例化模块用verilog表示为下面代码

srl16e #(.init(16'h0000)				 
) u_srl16_0(
	.d		(fpga_rst		),
	.clk	(s_osc_clk		),
	.q		(s_osc_rst		),
	.ce		(1'b1			),
	.a3		(1'b1			),
	.a2		(1'b1			),
	.a1		(1'b1			),
	.a0		(1'b1			)				
);

generic map

接下来就用到了vhdlgeneric mapport map 用法,二者都是vhdl中例化元件。前者是类属参数传递,也就是类属名称的例化,后者也就是一般的元件端口例化。而generic map的用法用verilog里面的参数parameter声明常量。所以直接用

U_DCM_SP : DCM_SP
   		generic map (
   		   CLKDV_DIVIDE 			=> 8.0					,
																
   		   CLKFX_DIVIDE 			=> 5					,
   		   CLKFX_MULTIPLY 			=> 4					,	
   		   CLKIN_DIVIDE_BY_2 		=> FALSE				,	
   		   CLKIN_PERIOD 			=> 20.0					,	
   		   CLKOUT_PHASE_SHIFT 		=> "NONE"				,	
   		   CLK_FEEDBACK 			=> "1X"					,	
   		   DESKEW_ADJUST 			=> "SYSTEM_SYNCHRONOUS" , 	
   		   DFS_FREQUENCY_MODE 		=> "LOW"				,	
   		   DLL_FREQUENCY_MODE 		=> "LOW"				,	
   		   DSS_MODE 				=> "NONE"				,	
   		   DUTY_CYCLE_CORRECTION 	=> TRUE					,	
   		   FACTORY_JF 				=> X"c080"				,	
   		   PHASE_SHIFT 				=> 0					,	
   		   STARTUP_WAIT 			=> FALSE                  	
   			)
   		port map (
   		   CLK0 					=> s_dcm1_clk0			,	
   		   CLK180 					=> open					,	
   		   CLK270 					=> open					,	
   		   CLK2X 					=> s_dcm1_clk2x			,	
   		   CLK2X180 				=> open					,	
   		   CLK90 					=> open					,	
   		   CLKDV 					=> s_dcm1_clkdv			,	
   		   CLKFX 					=> open					,	
   		   CLKFX180 				=> open					,	
   		   LOCKED 					=> s_dcm1_locked		,	
   		   PSDONE 					=> open					,	
   		   STATUS 					=> open					,	
   		   CLKFB 					=> s_dcm1_clk0_bufg		,	
   		   CLKIN 					=> s_osc_clk			,	
   		   DSSEN 					=> '0'					,	
   		   PSCLK 					=> '0'					,	
   		   PSEN 					=> '0'					,	
   		   PSINCDEC 				=> '0'					,	
   		   RST 						=> s_dcm_rst				
   		);

dcm_sp	#(											//
	.CLKDV_DIVIDE 			(8.0					),
   	.CLKFX_DIVIDE 			(5						),
   	.CLKFX_MULTIPLY 		(4						),
   	.CLKIN_DIVIDE_BY_2 		(FALSE					),
   	.CLKIN_PERIOD 			(20.0					),
   	.CLKOUT_PHASE_SHIFT 	(NONE					),
   	.CLK_FEEDBACK 			(1X						),
   	.DESKEW_ADJUST 			(SYSTEM_SYNCHRONOUS 	),
   	.DFS_FREQUENCY_MODE 	(LOW					),
   	.DLL_FREQUENCY_MODE 	(LOW					),
   	.DSS_MODE 				(NONE					),
   	.DUTY_CYCLE_CORRECTION 	(TRUE					),
   	.FACTORY_JF 			(16'hc080				),
   	.PHASE_SHIFT 			(0						),
   	.STARTUP_WAIT 			(FALSE                  )
) u_dcm_sp(
	.CLK0 					(s_dcm1_clk0			),
   	.CLK180 				(open					),
   	.CLK270 				(open					),
   	.CLK2X 					(s_dcm1_clk2x			),
   	.CLK2X180 				(open					),
   	.CLK90 					(open					),
   	.CLKDV 					(s_dcm1_clkdv			),
   	.CLKFX 					(open					),
   	.CLKFX180 				(open					),
   	.LOCKED 				(s_dcm1_locked			),
   	.PSDONE 				(open					),
   	.STATUS 				(open					),
   	.CLKFB 					(s_dcm1_clk0_bufg		),
   	.CLKIN 					(s_osc_clk				),
   	.DSSEN 					(0						),
   	.PSCLK 					(0						),
   	.PSEN 					(0						),
   	.PSINCDEC 				(0						),
   	.RST 					(s_dcm_rst				)
);						

这里引用到了数字时钟管理器(DCM),感兴趣的可以了解了解,这里不过多叙述。

assign

在vhdl例化模块后面或者其他地方会出现下面这样单独的几句赋值语句

    SYS_RST         <= not s_sys_locked ;
    SYS_CLK         <= s_dcm1_clk2x_bufg; 
    CAMMERA_PCLK    <= s_dcm1_clk0_bufg ;
    CMOS_XCLK       <= s_dcm1_clkdv_bufg;

这个用法及等同于verilog里面的assign赋值,直接转换

	assign 		sys_rst		= ~s_sys_locked		;
	assign    	sys_clk 	= s_dcm1_clk2x_bufg	; 
	assign    	camera_pclk = s_dcm1_clk0_bufg	;
	assign    	cmos_xclk	= s_dcm1_clkdv_bufg	;

是不是一目了然,除此之外,里面也少不了运算符的应用,接下来就讲解一下几个简单的运算符转换。

运算符

1,vhdl是没有&&、||、!这几个逻辑运算符,而verilog是有的;

2,vhdl是采用and、or、not、nor、xor进行位运算的,而verilog中则是采用与C/C++采用相同的:&、|、~、^、^~.

3,vhdl的关系运算符中等于和不等于分别是:= 、 /=,verilog中是:==、!=。

4,vhdl的连接运算符是&,用来连接不同的位/矢量,而verilog中使用的是{  ,  ,  ,}的方式。

所以上面遇到的例子可以这样转换

 SYS_RST <= not s_sys_locked ;
assign 		sys_rst		= ~s_sys_locked		;

常量constant与parameter

前面有说到过在vhdl例化模块中generic map类属名称例化等同于verilog中常量赋值parameter,现在就来说说vhdl中的常量赋值constant,谈及到vhdl中的赋值constant,固然少不了另外两种赋值signal、variable。

Signal即是“信号”的意思,它具有特定的物理意义,一般对应电路中特定的物理连线或存储单元。Signal是VHDL语法中最重要、最常用的一种可赋值对象。当程序中需要用到signal时,我们一般需要在VHDL基本程序框架中的architecture语法的声明与定义部分先声明一个signal,然后才能在architecture的语句部分使用它。 Signal的声明语法如下:
signal <signal_name> : := ; – 有初值

signal <signal_name> : ; – 无初值


Variable即是“变量”的意思,它不具有特定的物理意义,对应关系也不太直接,通常只代表暂存某些值的载体。** 在之前介绍的VHDL基本程序框架中,可以看到variable出现在process语句中,作为process的局部变量来使用。** 当程序中要用到variable时,只需要在process语法的敏感量列表与begin关键字之间先声明一个variable,然后就能在process的语句体中使用它。Variable的声明语法如下:
variable : := ; – 有初值

variable : ; – 无初值


Constant即是“常量”的意思,它具有特定的物理意义,通常对应数字电路中的电源或者地。Constant能出现在所有signal和variable出现的场合中,它的声明语法如下:
constant : := ;
可以注意到,常量是不能单独赋值的,仅仅能在声明的同时被初始化赋值。

vhdl中常量赋值Constant对应verilog中的常量赋值parameter,所以遇到直接转换

	constant 	c_cam_pix_cnt  				:	std_logic_vector(15 downto 0)	:= x"04ff"; 
	constant	c_cam_line_cnt              :	std_logic_vector(15 downto 0)	:= x"03FF"; 
parameter [15:0] c_cam_pix_cn   = 16'h04ff;
parameter [15:0] c_cam_line_cnt = 16'h03ff;

怎么样?改过来是不是简单明了多了?今天就先到这里,同样有什么问题或者你也像我一样很不幸也需要翻译的话,遇到问题也可以在评论区交流探讨一下,后续再翻译的结果会继续跟上的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值