1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_clgen.v ////
//// ////
//// This file is part of the SPI IP core project ////
//// http://www.opencores.org/projects/spi/ ////
//// ////
//// Author(s): ////
//// - Simon Srot (simons@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
`include "spi_defines.v"
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
input clk_in; // input clock (system clock)
input rst; // reset
input enable; // clock enable
input go; // start transfer
input last_clk; // last clock
input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value)
output clk_out; // output clock
output pos_edge; // pulse marking positive edge of clk_out
output neg_edge; // pulse marking negative edge of clk_out
reg clk_out;
reg pos_edge;
reg neg_edge;
reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
wire cnt_zero; // conter is equal to zero
wire cnt_one; // conter is equal to one
assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
// Counter counts half period
always @(posedge clk_in)
begin
if(rst)
cnt <= {`SPI_DIVIDER_LEN{1'b1}};
else
begin
if(!enable || cnt_zero)
cnt <= divider;
else
cnt <= cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
end
end
// clk_out is asserted every other half period
always @(posedge clk_in)
begin
if(rst)
clk_out <= 1'b0;
else
clk_out <= (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
// Pos and neg edge signals
always @(posedge clk_in)
begin
if(rst)
begin
pos_edge <= 1'b0;
neg_edge <= 1'b0;
end
else
begin
pos_edge <= (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
neg_edge <= (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
end
end
endmodule
|