OpenCores
URL https://opencores.org/ocsvn/ptc/ptc/trunk

Subversion Repositories ptc

[/] [ptc/] [trunk/] [rtl/] [verilog/] [ptc_top.v] - Rev 13

Go to most recent revision | Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  WISHBONE PWM/Timer/Counter                                  ////
////                                                              ////
////  This file is part of the PTC project                        ////
////  http://www.opencores.org/cores/ptc/                         ////
////                                                              ////
////  Description                                                 ////
////  Implementation of PWM/Timer/Counter IP core according to    ////
////  PTC IP core specification document.                         ////
////                                                              ////
////  To Do:                                                      ////
////   Nothing                                                    ////
////                                                              ////
////  Author(s):                                                  ////
////      - Damjan Lampret, lampret@opencores.org                 ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
////                                                              ////
//// 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                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.4  2001/09/18 18:48:29  lampret
// Changed top level ptc into ptc_top. Changed defines.v into ptc_defines.v. Reset of the counter is now synchronous.
//
// Revision 1.3  2001/08/21 23:23:50  lampret
// Changed directory structure, defines and port names.
//
// Revision 1.2  2001/07/17 00:18:10  lampret
// Added new parameters however RTL still has some issues related to hrc_match and int_match
//
// Revision 1.1  2001/06/05 07:45:36  lampret
// Added initial RTL and test benches. There are still some issues with these files.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "ptc_defines.v"
 
module ptc_top(
	// WISHBONE Interface
	wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i,
	wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o,
 
	// External PTC Interface
	gate_clk_pad_i, capt_pad_i, pwm_pad_o, oen_padoen_o
);
 
parameter dw = 32;
parameter aw = `PTC_ADDRHH+1;
parameter cw = `PTC_CW;
 
//
// WISHBONE Interface
//
input			wb_clk_i;	// Clock
input			wb_rst_i;	// Reset
input			wb_cyc_i;	// cycle valid input
input 	[aw-1:0]	wb_adr_i;	// address bus inputs
input	[dw-1:0]	wb_dat_i;	// input data bus
input	[3:0]		wb_sel_i;	// byte select inputs
input			wb_we_i;	// indicates write transfer
input			wb_stb_i;	// strobe input
output	[dw-1:0]	wb_dat_o;	// output data bus
output			wb_ack_o;	// normal termination
output			wb_err_o;	// termination w/ error
output			wb_inta_o;	// Interrupt request output
 
//
// External PTC Interface
//
input		gate_clk_pad_i;	// EClk/Gate input
input		capt_pad_i;	// Capture input
output		pwm_pad_o;	// PWM output
output		oen_padoen_o;	// PWM output driver enable
 
`ifdef PTC_IMPLEMENTED
 
//
// PTC Main Counter Register (or no register)
//
`ifdef PTC_RPTC_CNTR
reg	[cw-1:0]	rptc_cntr;	// RPTC_CNTR register
`else
wire	[cw-1:0]	rptc_cntr;	// No RPTC_CNTR register
`endif
 
//
// PTC HI Reference/Capture Register (or no register)
//
`ifdef PTC_RPTC_HRC
reg	[cw-1:0]	rptc_hrc;	// RPTC_HRC register
`else
wire	[cw-1:0]	rptc_hrc;	// No RPTC_HRC register
`endif
 
//
// PTC LO Reference/Capture Register (or no register)
//
`ifdef PTC_RPTC_LRC
reg	[cw-1:0]	rptc_lrc;	// RPTC_LRC register
`else
wire	[cw-1:0]	rptc_lrc;	// No RPTC_LRC register
`endif
 
//
// PTC Control Register (or no register)
//
`ifdef PTC_RPTC_CTRL
reg	[8:0]		rptc_ctrl;	// RPTC_CTRL register
`else
wire	[8:0]		rptc_ctrl;	// No RPTC_CTRL register
`endif
 
//
// Internal wires & regs
//
wire			rptc_cntr_sel;	// RPTC_CNTR select
wire			rptc_hrc_sel;	// RPTC_HRC select
wire			rptc_lrc_sel;	// RPTC_LRC select
wire			rptc_ctrl_sel;	// RPTC_CTRL select
wire			hrc_match;	// RPTC_HRC matches RPTC_CNTR
wire			lrc_match;	// RPTC_LRC matches RPTC_CNTR
wire			restart;	// Restart counter when asserted
wire			stop;		// Stop counter when asserted
wire			cntr_clk;	// Counter clock
wire			cntr_rst;	// Counter reset
wire			hrc_clk;	// RPTC_HRC clock
wire			lrc_clk;	// RPTC_LRC clock
wire			eclk_gate;	// ptc_ecgt xored by RPTC_CTRL[NEC]
wire			gate;		// Gate function of ptc_ecgt
wire			pwm_rst;	// Reset of a PWM output
reg	[dw-1:0]	wb_dat_o;	// Data out
reg			pwm_pad_o;	// PWM output
reg			int;		// Interrupt reg
wire			int_match;	// Interrupt match
wire			full_decoding;	// Full address decoding qualification
 
//
// All WISHBONE transfer terminations are successful except when:
// a) full address decoding is enabled and address doesn't match
//    any of the PTC registers
// b) sel_i evaluation is enabled and one of the sel_i inputs is zero
//
assign wb_ack_o = wb_cyc_i & wb_stb_i & !wb_err_o;
`ifdef PTC_FULL_DECODE
`ifdef PTC_STRICT_32BIT_ACCESS
assign wb_err_o = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
`else
assign wb_err_o = wb_cyc_i & wb_stb_i & !full_decoding;
`endif
`else
`ifdef PTC_STRICT_32BIT_ACCESS
assign wb_err_o = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
`else
assign wb_err_o = 1'b0;
`endif
`endif
 
//
// Counter clock is selected by RPTC_CTRL[ECLK]. When it is set,
// external clock is used.
//
assign cntr_clk = rptc_ctrl[`PTC_RPTC_CTRL_ECLK] ? eclk_gate : wb_clk_i;
 
//
// Counter reset
//
assign cntr_rst = wb_rst_i;
 
//
// HRC clock is selected by RPTC_CTRL[CAPTE]. When it is set,
// ptc_capt is used as a clock.
//
assign hrc_clk = rptc_ctrl[`PTC_RPTC_CTRL_CAPTE] ? capt_pad_i : wb_clk_i;
 
//
// LRC clock is selected by RPTC_CTRL[CAPTE]. When it is set,
// inverted ptc_capt is used as a clock.
//
assign lrc_clk = rptc_ctrl[`PTC_RPTC_CTRL_CAPTE] ? ~capt_pad_i : wb_clk_i;
 
//
// PWM output driver enable is inverted RPTC_CTRL[OE]
//
assign oen_padoen_o = ~rptc_ctrl[`PTC_RPTC_CTRL_OE];
 
//
// Use RPTC_CTRL[NEC]
//
assign eclk_gate = gate_clk_pad_i ^ rptc_ctrl[`PTC_RPTC_CTRL_NEC];
 
//
// Gate function is active when RPTC_CTRL[ECLK] is cleared
//
assign gate = eclk_gate & ~rptc_ctrl[`PTC_RPTC_CTRL_ECLK];
 
//
// Full address decoder
//
`ifdef PTC_FULL_DECODE
assign full_decoding = (wb_adr_i[`PTC_ADDRHH:`PTC_ADDRHL] == {`PTC_ADDRHH-`PTC_ADDRHL+1{1'b0}}) &
			(wb_adr_i[`PTC_ADDRLH:`PTC_ADDRLL] == {`PTC_ADDRLH-`PTC_ADDRLL+1{1'b0}});
`else
assign full_decoding = 1'b1;
`endif
 
//
// PTC registers address decoder
//
assign rptc_cntr_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_CNTR) & full_decoding;
assign rptc_hrc_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_HRC) & full_decoding;
assign rptc_lrc_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_LRC) & full_decoding;
assign rptc_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_CTRL) & full_decoding;
 
//
// Write to RPTC_CTRL or update of RPTC_CTRL[INT] bit
//
`ifdef PTC_RPTC_CTRL
always @(posedge wb_clk_i or posedge wb_rst_i)
	if (wb_rst_i)
		rptc_ctrl <= #1 9'b0;
	else if (rptc_ctrl_sel && wb_we_i)
		rptc_ctrl <= #1 wb_dat_i[8:0];
	else if (rptc_ctrl[`PTC_RPTC_CTRL_INTE])
		rptc_ctrl[`PTC_RPTC_CTRL_INT] <= #1 rptc_ctrl[`PTC_RPTC_CTRL_INT] | int;
`else
assign rptc_ctrl = `PTC_DEF_RPTC_CTRL;
`endif
 
//
// Write to RPTC_HRC
//
`ifdef PTC_RPTC_HRC
always @(posedge hrc_clk or posedge wb_rst_i)
	if (wb_rst_i)
		rptc_hrc <= #1 {cw{1'b0}};
	else if (rptc_hrc_sel && wb_we_i)
		rptc_hrc <= #1 wb_dat_i[cw-1:0];
	else if (rptc_ctrl[`PTC_RPTC_CTRL_CAPTE])
		rptc_hrc <= #1 rptc_cntr;
`else
assign rptc_hrc = `DEF_RPTC_HRC;
`endif
 
//
// Write to RPTC_LRC
//
`ifdef PTC_RPTC_LRC
always @(posedge lrc_clk or posedge wb_rst_i)
	if (wb_rst_i)
		rptc_lrc <= #1 {cw{1'b0}};
	else if (rptc_lrc_sel && wb_we_i)
		rptc_lrc <= #1 wb_dat_i[cw-1:0];
	else if (rptc_ctrl[`PTC_RPTC_CTRL_CAPTE])
		rptc_lrc <= #1 rptc_cntr;
`else
assign rptc_lrc = `DEF_RPTC_LRC;
`endif
 
//
// Write to or increment of RPTC_CNTR
//
`ifdef PTC_RPTC_CNTR
always @(posedge cntr_clk or posedge cntr_rst)
	if (cntr_rst)
		rptc_cntr <= #1 {cw{1'b0}};
	else if (rptc_cntr_sel && wb_we_i)
		rptc_cntr <= #1 wb_dat_i[cw-1:0];
	else if (restart)
		rptc_cntr <= #1 {cw{1'b0}};
	else if (!stop && rptc_ctrl[`PTC_RPTC_CTRL_EN] && !gate)
		rptc_cntr <= #1 rptc_cntr + 1;
`else
assign rptc_cntr = `DEF_RPTC_CNTR;
`endif
 
//
// Read PTC registers
//
always @(wb_adr_i or rptc_hrc or rptc_lrc or rptc_ctrl or rptc_cntr)
	case (wb_adr_i[`PTC_OFS_BITS])	// synopsys full_case parallel_case
`ifdef PTC_READREGS
		`PTC_RPTC_HRC: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_hrc};
		`PTC_RPTC_LRC: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_lrc};
		`PTC_RPTC_CTRL: wb_dat_o[dw-1:0] = {{dw-9{1'b0}}, rptc_ctrl};
`endif
		default: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_cntr};
	endcase
 
//
// A match when RPTC_HRC is equal to RPTC_CNTR
//
assign hrc_match = rptc_ctrl[`PTC_RPTC_CTRL_EN] & (rptc_cntr == rptc_hrc);
 
//
// A match when RPTC_LRC is equal to RPTC_CNTR
//
assign lrc_match = rptc_ctrl[`PTC_RPTC_CTRL_EN] & (rptc_cntr == rptc_lrc);
 
//
// Restart counter when lrc_match asserted and RPTC_CTRL[SINGLE] cleared
// or when RPTC_CTRL[CNTRRST] is set
//
assign restart = lrc_match & ~rptc_ctrl[`PTC_RPTC_CTRL_SINGLE]
	| rptc_ctrl[`PTC_RPTC_CTRL_CNTRRST];
 
//
// Stop counter when lrc_match and RPTC_CTRL[SINGLE] both asserted
//
assign stop = lrc_match & rptc_ctrl[`PTC_RPTC_CTRL_SINGLE];
 
//
// PWM reset when lrc_match or system reset
//
assign pwm_rst = lrc_match | wb_rst_i;
 
//
// PWM output
//
always @(posedge wb_clk_i)	// posedge pwm_rst or posedge hrc_match !!! Damjan
	if (pwm_rst)
		pwm_pad_o <= #1 1'b0;
	else if (hrc_match)
		pwm_pad_o <= #1 1'b1;
 
//
// Generate an interrupt request
//
assign int_match = (lrc_match | hrc_match) & rptc_ctrl[`PTC_RPTC_CTRL_INTE];
 
// Register interrupt request
always @(posedge wb_rst_i or posedge wb_clk_i) // posedge int_match (instead of wb_rst_i)
	if (wb_rst_i)
		int <= #1 1'b0;
	else if (int_match)
		int <= #1 1'b1;
	else
		int <= #1 1'b0;
 
//
// Alias
//
assign wb_inta_o = rptc_ctrl[`PTC_RPTC_CTRL_INT];
 
`else
 
//
// When PTC is not implemented, drive all outputs as would when RPTC_CTRL
// is cleared and WISHBONE transfers complete with errors
//
assign wb_inta_o = 1'b0;
assign wb_ack_o = 1'b0;
assign wb_err_o = cyc_i & stb_i;
assign pwm_pad_o = 1'b0;
assign oen_padoen_o = 1'b1;
 
//
// Read PTC registers
//
`ifdef PTC_READREGS
assign wb_dat_o = {dw{1'b0}};
`endif
 
`endif
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.