下面给出三种分频实验的代码,并给出RTL综合图和资源消耗量,并给出我个人的分析。
//===========================================================================
div0是从VHDL的书本例子改写的。
--示波器实测 1.00001KHz.
代码见
//=========================================================================== // Created by : Casio // Filename : div0.v // Author : // Created On : 2013-04-24 16:40 // Last Modified : 2013-04-24 17:47 // // // Revision:: // // Description:这个例子是从VHDL书《VHDL数字电路设计教程》ISBN:7-121-01743-1 P111页 例7.5得来 // --示波器实测 1.00001KHz. 实际资源耗费如下: //Resource Usage //Total logic elements 62 //-- Combinational with no register 37 //-- Register only 9 //-- Combinational with a register 16 // //Logic element usage by number of LUT inputs //-- 4 input functions 15 //-- 3 input functions 1 //-- 2 input functions 35 //-- 1 input functions 2 //-- 0 input functions 0 // //Logic elements by mode //-- normal mode 36 //-- arithmetic mode 26 //-- qfbk mode 0 //-- register cascade mode 0 //-- synchronous clear/load mode 0 //-- asynchronous clear/load mode 0 // //Total registers 25 //Total logic cells in carry chains 28 //I/O pins 3 //Maximum fan-out node clk //Maximum fan-out 25 //Total fan-out 171 //Average fan-out 2.63 //分频算法为: // --24000000 (24MHz) / 12000 * 2 = 1000 Hz (1KHz) //这个例子的优势在于对于多通道输出,分频数不同,但是要求相位一致的分频器是一个不错的选择. //代码如下: // ---------------------- // LIBRARY ieee; // USE ieee.std_logic_1164.all; // ---------------------- // ENTITY freq_divider IS // generic (CNT: integer := 12000); // PORT (clk: IN STD_LOGIC; // out1, out2: BUFFER STD_LOGIC); // END freq_divider; // ---------------------- // ARCHITECTURE example OF freq_divider IS // SIGNAL count1: INTEGER RANGE 0 TO 15000; // BEGIN // PROCESS (clk) // VARIABLE count2: INTEGER RANGE 0 TO 15000; // BEGIN // IF (clk'EVENT AND clk = '1') THEN // count1 <= count1 + 1; // count2 := count2 + 1; // IF (count1 = CNT-1) THEN --修改此处代码为CNT-6001后,out1输出2KHz,示波器实测 2.00002KHz // out1 <= NOT out1; // count1 <= 0; // END IF; // IF (count2 = CNT) THEN // out2 <= NOT out2; // count2 := 0; // END IF; // END IF; // END PROCESS; // END example; // ---------------------- // //=========================================================================== //下面是经过改写成Verilog的资源消耗情况: //从RTL图上可以发现,改写后的代码和改写前的VHDL的RTL视图是一样的. //从示波器看输出端和VHDL的情况一样1.00001KHz和2.00002KHz. //Resource Usage //Total logic elements 64 //-- Combinational with no register 38 //-- Register only 10 //-- Combinational with a register 16 // //Logic element usage by number of LUT inputs //-- 4 input functions 8 //-- 3 input functions 0 //-- 2 input functions 44 //-- 1 input functions 2 //-- 0 input functions 0 // //Logic elements by mode //-- normal mode 38 //-- arithmetic mode 26 //-- qfbk mode 0 //-- register cascade mode 0 //-- synchronous clear/load mode 0 //-- asynchronous clear/load mode 0 // //Total registers 26 //Total logic cells in carry chains 28 //I/O pins 3 //Maximum fan-out node clk //Maximum fan-out 26 //Total fan-out 160 //Average fan-out 2.39 //=========================================================================== module div0( //Input Ports clk, //Output Ports out1, out2 ); parameter CNT1 = 14'd12000; parameter CNT2 = 14'd6000; //=========================================================================== //Input and output declaration //=========================================================================== input clk; output out1; output out2; //=========================================================================== //Wire and reg declaration //=========================================================================== wire clk; wire out1; wire out2; //=========================================================================== //Wire and reg in the module //=========================================================================== reg [13:0] count1; //2^14 = 16384 > 12000 reg [13:0] count2; reg out1_r; reg out2_r; //=========================================================================== //Logic //=========================================================================== assign out1 = out1_r; assign out2 = out2_r; always @ (posedge clk) begin count1 = count1 + 1; if (count1 == CNT1) begin count1 <= 1'b0; out1_r <= ~out1_r; end end always @ (posedge clk) begin count2 = count2 + 1; if (count2 == CNT2) begin count2 <= 0; out2_r <= ~out2_r; end end endmodule
RTL视图见
这个例子的优势在于对于多通道输出,分频数不同,但是要求相位一致的分频器是一个不错的选择.
//===========================================================================
div1是学校的教学实验中的例子。原文为VHDL。改写为Verilog。
--示波器实测 1.00001KHz.
Verilog代码见
/* * 分频方法来自学校教学实验中的例子,原文为VHDL.现使用verilog改写 *=========================================================================================== * --文件名:baud.vhd. * --功能:本实验想要实现的波特率为:24MHz = 24000000 / 2 * 1000 = 12000 * library IEEE; * use IEEE.STD_LOGIC_1164.ALL; * use IEEE.STD_LOGIC_ARITH.ALL; * use IEEE.STD_LOGIC_UNSIGNED.ALL; * entity baud is * generic (framlenr: integer := 12000); * port ( clk, resetb: in std_logic; * bclk: buffer std_logic * ); * end baud; * * architecture Behavioral of baud is * begin * process(clk,resetb) * variable cnt:integer := 0; * begin * if resetb='0' then * cnt:=0; * bclk<='0'; --复位 * elsif (clk'event and clk = '1') then * if cnt > framlenr then * cnt := 0; * bclk <= NOT bclk;--设置分频系数 * else * cnt := cnt+1; * --bclk <= '0'; * end if; * end if; * end process; * end Behavioral; *=========================================================================================== * */ //Verilog版本的代码使用资源如下,可以看出尽管只有一路输出,但是占用资源还是很大的: //Resource Usage //Total logic elements 75 //-- Combinational with no register 42 //-- Register only 25 //-- Combinational with a register 8 // //Logic element usage by number of LUT inputs //-- 4 input functions 10 //-- 3 input functions 8 //-- 2 input functions 31 //-- 1 input functions 1 //-- 0 input functions 0 // //Logic elements by mode //-- normal mode 44 //-- arithmetic mode 31 //-- qfbk mode 0 //-- register cascade mode 0 //-- synchronous clear/load mode 0 //-- asynchronous clear/load mode 33 // //Total registers 33 //Total logic cells in carry chains 32 //I/O pins 3 //Maximum fan-out node clk //Maximum fan-out 33 //Total fan-out 219 //Average fan-out 2.81 module div1( clk, rst_n, out1); input clk, rst_n; output out1; integer cnt; reg out1; parameter framlenr = 11999; always @(posedge clk, negedge rst_n) begin if (!rst_n) begin cnt <= 0; out1 <= 1'b0; end else if (cnt == framlenr) begin cnt <= 0; out1 <= ~out1; end else cnt <= cnt + 1; end endmodule
RTL视图见
//===========================================================================
div2是特权同学的例子。(光盘中)
光盘中的例子给了一个很好的创新,把计数器和引脚翻转分开,每个always只做一件事情.并且我个人认为同步性最好.不过资源占用最大.
--示波器实测 1.00001KHz.
Verilog代码见
//资源消耗如下,可以看出这种方法的资源消耗还是很大的: //Resource Usage //Total logic elements 144 //-- Combinational with no register 82 //-- Register only 46 //-- Combinational with a register 16 // //Logic element usage by number of LUT inputs //-- 4 input functions 19 //-- 3 input functions 16 //-- 2 input functions 62 //-- 1 input functions 1 //-- 0 input functions 0 // //Logic elements by mode //-- normal mode 83 //-- arithmetic mode 61 //-- qfbk mode 0 //-- register cascade mode 0 //-- synchronous clear/load mode 0 //-- asynchronous clear/load mode 62 // //Total registers 62 //Total logic cells in carry chains 63 //I/O pins 4 //Maximum fan-out node clk //Maximum fan-out 62 //Total fan-out 421 //Average fan-out 2.84 //--------------------------------------------------- module div2( clk, rst_n, out1, out2); input clk; //50MHz input rst_n; //低电平复位信号 output out1; output out2; //--------------------------------------------------- integer cnt1; //分频计数器 always @ (posedge clk or negedge rst_n) //异步复位 if(!rst_n) cnt1 <= 0; else if (cnt1 == 11999) cnt1 <= 0; else cnt1 <= cnt1 + 1; //---------------------------------------------------- reg out1_r; //信号值寄存器 always @ (posedge clk or negedge rst_n) if(!rst_n) out1_r <= 1'b0; else if(cnt1 == 11999) out1_r <= ~out1_r; assign out1 = out1_r; //--------------------------------------------------- integer cnt2; //分频计数器 always @ (posedge clk or negedge rst_n) //异步复位 if(!rst_n) cnt2 <= 0; else if (cnt2 == 5999) cnt2 <= 0; else cnt2 <= cnt2 + 1; //---------------------------------------------------- reg out2_r; //信号值寄存器 always @ (posedge clk or negedge rst_n) if(!rst_n) out2_r <= 1'b0; else if(cnt2 == 5999) out2_r <= ~out2_r; assign out2 = out2_r; //--------------------------------------------------- endmodule
RTL视图见div2.JPG
//===========================================================================
div3也是特权同学的例子,不过是视频当中直接讲解的。
--示波器实测 1.00001KHz.
Verilog代码见
//本例中的资源消耗最少.不过示波器实测还是1.00001KHz //该例子的缺点是不能使用任意数进行计数分频,比如,如果计数器的计数为7,则7不能被2整除,所以使用范围受到限制. //Resource Usage //Total logic elements 97 //-- Combinational with no register 33 //-- Register only 0 //-- Combinational with a register 64 // //Logic element usage by number of LUT inputs //-- 4 input functions 26 //-- 3 input functions 3 //-- 2 input functions 66 //-- 1 input functions 2 //-- 0 input functions 0 // //Logic elements by mode //-- normal mode 35 //-- arithmetic mode 62 //-- qfbk mode 0 //-- register cascade mode 0 //-- synchronous clear/load mode 64 //-- asynchronous clear/load mode 64 // //Total registers 64 //Total logic cells in carry chains 64 //I/O pins 4 //Maximum fan-out node clk //Maximum fan-out 64 //Total fan-out 441 //Average fan-out 4.37 //---------------------------------------------- module div3( clk, rst_n, out1, out2); input clk, rst_n; output out1; output out2; //---------------------------------------------------- integer cnt1; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt1 <= 0; else if (cnt1 < 11999) cnt1 <= cnt1 + 1; else cnt1 <= 0; end assign out1 = (cnt1 <= 5999) ? 1'b0 : 1'b1; //---------------------------------------------------- integer cnt2; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt2 <= 0; else if (cnt2 < 23999) cnt2 <= cnt2 + 1; else cnt2 <= 0; end assign out2 = (cnt2 <= 11999) ? 1'b0 : 1'b1; //---------------------------------------------------- endmodule
RTL视图见div3.JPG
本例中的资源消耗最少.
该例子的缺点是不能使用任意数进行计数分频,比如,如果计数器的计数为7,则7不能被2整除,所以使用范围受到限制.
//===========================================================================