?? uart_baud_gen.v
字號:
//-----------------------------------------------------------------------------// // Copyright (c) 2008 Xilinx Inc.//// Project : Programmable Wave Generator// Module : uart_baud_gen.v// Parent : uart_rx and uart_tx// Children : None//// Description: // Generates a 16x Baud enable. This signal is generated 16 times per bit// at the correct baud rate as determined by the parameters for the system// clock frequency and the Baud rate//// Parameters:// BAUD_RATE : Baud rate - set to 57,600bps by default// CLOCK_RATE: Clock rate - set to 50MHz by default//// Local Parameters:// OVERSAMPLE_RATE: The oversampling rate - 16 x BAUD_RATE// DIVIDER : The number of clocks per baud_x16_en// CNT_WIDTH : Width of the counter//// Notes : // 1) Divider must be at least 2 (thus CLOCK_RATE must be at least 32x// BAUD_RATE)//// Multicycle and False Paths// None//`timescale 1ns/1psmodule uart_baud_gen ( // Write side inputs input clk, // Clock input input rst, // Active HIGH reset - synchronous to clk output baud_x16_en // Oversampled Baud rate enable);//***************************************************************************// Constant Functions//*************************************************************************** // Generate the ceiling of the log base 2 - i.e. the number of bits // required to hold N values. A vector of size clogb2(N) will hold the // values 0 to N-1 function integer clogb2; input [31:0] value; reg [31:0] my_value; begin my_value = value - 1; for (clogb2 = 0; my_value > 0; clogb2 = clogb2 + 1) my_value = my_value >> 1; end endfunction ////***************************************************************************// Parameter definitions//*************************************************************************** parameter BAUD_RATE = 57_600; // Baud rate parameter CLOCK_RATE = 50_000_000; // The OVERSAMPLE_RATE is the BAUD_RATE times 16 localparam OVERSAMPLE_RATE = BAUD_RATE * 16; // The divider is the CLOCK_RATE / OVERSAMPLE_RATE - rounded up // (so add 1/2 of the OVERSAMPLE_RATE before the integer division) localparam DIVIDER = (CLOCK_RATE+OVERSAMPLE_RATE/2) / OVERSAMPLE_RATE; // The value to reload the counter is DIVIDER-1; localparam OVERSAMPLE_VALUE = DIVIDER - 1; // The required width of the counter is the ceiling of the base 2 logarithm // of the DIVIDER localparam CNT_WID = clogb2(DIVIDER);//***************************************************************************// Reg declarations//*************************************************************************** reg [CNT_WID-1:0] internal_count; reg baud_x16_en_reg;//***************************************************************************// Wire declarations//*************************************************************************** wire [CNT_WID-1:0] internal_count_m_1; // Count minus 1//***************************************************************************// Code//*************************************************************************** assign internal_count_m_1 = internal_count - 1'b1; // Count from DIVIDER-1 to 0, setting baud_x16_en_reg when internal_count=0. // The signal baud_x16_en_reg must come from a flop (since it is a module // output) so schedule it to be set when the next count is 1 (i.e. when // internal_count_m_1 is 0). always @(posedge clk) begin if (rst) begin internal_count <= OVERSAMPLE_VALUE; baud_x16_en_reg <= 1'b0; end else begin // Assert baud_x16_en_reg in the next clock when internal_count will be // zero in that clock (thus when internal_count_m_1 is 0). baud_x16_en_reg <= (internal_count_m_1 == {CNT_WID{1'b0}}); // Count from OVERSAMPLE_VALUE down to 0 repeatedly if (internal_count == {CNT_WID{1'b0}}) begin internal_count <= OVERSAMPLE_VALUE; end else // internal_count is not 0 begin internal_count <= internal_count_m_1; end end // if rst end // always assign baud_x16_en = baud_x16_en_reg;endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -