URL
https://opencores.org/ocsvn/rtc/rtc/trunk
Subversion Repositories rtc
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/trunk/bench/verilog/tb_defines.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/08/21 12:53:10 lampret |
// Changed directory structure, uniquified defines and changed design's port names. |
// |
// Revision 1.3 2001/07/16 01:05:01 lampret |
// Fixed some bugs in test bench. Added comments to tb_defines.v |
// |
64,4 → 67,4
// |
// Define if you want VCD dump |
// |
//`define RTC_DUMP_VCD |
`define RTC_DUMP_VCD |
/trunk/bench/verilog/tb_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/08/21 12:53:10 lampret |
// Changed directory structure, uniquified defines and changed design's port names. |
// |
// Revision 1.1 2001/06/05 07:45:41 lampret |
// Added initial RTL and test benches. There are still some issues with these files. |
// |
109,7 → 112,7
// |
// Instantiation of RTC core |
// |
rtc rtc( |
rtc_top rtc_top( |
// WISHBONE Interface |
.wb_clk_i(clk), |
.wb_rst_i(rst), |
/trunk/bench/verilog/tb_tasks.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/08/21 12:53:10 lampret |
// Changed directory structure, uniquified defines and changed design's port names. |
// |
// Revision 1.2 2001/07/16 01:05:01 lampret |
// Fixed some bugs in test bench. Added comments to tb_defines.v |
// |
56,7 → 59,7
`include "timescale.v" |
// synopsys translate_on |
|
`include "defines.v" |
`include "rtc_defines.v" |
`include "tb_defines.v" |
|
module tb_tasks; |
568,7 → 571,6
// Phase 1 and 2 should be equal and non-zero. |
// Phase 3 should be more than 1 or 2. |
// |
$display("xxxx", l1, l2, l3); |
if (l1 && (l1 == l2) && (l3 > l2)) |
$display(" OK"); |
else |
1125,7 → 1127,7
a1 = ctrl[`RTC_RRTC_CTRL_ALRM]; |
|
// Is alarm flag set and interrupt cleared? |
if ((a1 > a0) && !tb_top.rtc.wb_inta_o) |
if ((a1 > a0) && !tb_top.rtc_top.wb_inta_o) |
$display(" OK"); |
else |
failed; |
1169,7 → 1171,7
a1 = ctrl[`RTC_RRTC_CTRL_ALRM]; |
|
// Is alarm flag set and interrupt asserted? |
if ((a1 > a0) && tb_top.rtc.wb_inta_o) |
if ((a1 > a0) && tb_top.rtc_top.wb_inta_o) |
$display(" OK"); |
else |
failed; |
1182,7 → 1184,7
|
// Is interrupt request still asserted? |
tb_top.wb_master.rd(`RTC_RRTC_CTRL<<2, ctrl); |
if (!tb_top.rtc.wb_inta_o) |
if (!tb_top.rtc_top.wb_inta_o) |
$display(" OK"); |
else |
failed; |
1242,7 → 1244,6
$display(" OK"); |
else |
failed; |
|
end |
|
endtask |
1362,7 → 1363,7
// |
initial begin |
`ifdef RTC_DUMP_VCD |
$dumpfile("../sim/tb_top.vcd"); |
$dumpfile("../out/tb_top.vcd"); |
$dumpvars(3, tb_top); |
`endif |
nr_failed = 0; |
/trunk/rtl/verilog/rtc_defines.v
0,0 → 1,232
////////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE Real-Time Clock Definitions //// |
//// //// |
//// This file is part of the RTC project //// |
//// http://www.opencores.org/cores/rtc/ //// |
//// //// |
//// Description //// |
//// RTC definitions. //// |
//// //// |
//// 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.1 2001/08/21 12:53:11 lampret |
// Changed directory structure, uniquified defines and changed design's port names. |
// |
// Revision 1.2 2001/07/16 01:08:45 lampret |
// Added additional parameters to make RTL more configurable. Added bunch of comments to defines.v |
// |
// Revision 1.1 2001/06/05 07:45:43 lampret |
// Added initial RTL and test benches. There are still some issues with these files. |
// |
// |
|
// |
// Undefine this one if you don't want to remove RTC block from your design |
// but you also don't need it. When it is undefined, all RTC ports still |
// remain valid and the core can be synthesized however internally there is |
// no RTC funationality. |
// |
// Defined by default (duhh !). |
// |
`define RTC_IMPLEMENTED |
|
// |
// Undefine if you don't need to read RTC registers. |
// When it is undefined all reads of RTC registers return zero. This |
// is usually useful if you want really small area (for example when |
// implemented in FPGA). |
// |
// To follow RTC IP core specification document this one must be defined. |
// Also to successfully run the test bench it must be defined. By default |
// it is defined. |
// |
`define RTC_READREGS |
|
// |
// Undefine if you don't need RTC internal clock divider circuitry. Without |
// divider RTC is clocked directly by WISHBONE or external clock. |
// |
// To follow RTC IP core specification document this one must be defined. Also to |
// successfully run the test bench it must be defined. By default it is defined. |
// |
`define RTC_DIVIDER |
|
// |
// Full WISHBONE address decoding |
// |
// It is is undefined, partial WISHBONE address decoding is performed. |
// Undefine it if you need to save some area. |
// |
// By default it is defined. |
// |
`define RTC_FULL_DECODE |
|
// |
// Strict 32-bit WISHBONE access |
// |
// If this one is defined, all WISHBONE accesses must be 32-bit. If it is |
// not defined, err_o is asserted whenever 8- or 16-bit access is made. |
// Undefine it if you need to save some area. |
// |
// By default it is defined. |
// |
`define RTC_STRICT_32BIT_ACCESS |
|
// |
// WISHBONE address bits used for full decoding of RTC registers. |
// |
`define RTC_ADDRHH 15 |
`define RTC_ADDRHL 5 |
`define RTC_ADDRLH 1 |
`define RTC_ADDRLL 0 |
|
// |
// Bits of WISHBONE address used for partial decoding of RTC registers. |
// |
// Default 4:2. |
// |
`define RTC_OFS_BITS `RTC_ADDRHL-1:`RTC_ADDRLH+1 |
|
// |
// Addresses of RTC registers |
// |
// To comply with RTC IP core specification document they must go from |
// address 0 to address 0x10 in the following order: RRTC_TIME, RRTC_DATE, |
// RRTC_TALRM, RRTC_DALRM and RRTC_CTRL |
// |
// If particular alarm/ctrl register is not needed, it's address definition |
// can be omitted and the register will not be implemented. Instead a fixed |
// default value will |
// be used. |
// |
`define RTC_RRTC_TIME 3'h0 // Address 0x00 |
`define RTC_RRTC_DATE 3'h1 // Address 0x04 |
`define RTC_RRTC_TALRM 3'h2 // Address 0x08 |
`define RTC_RRTC_DALRM 3'h3 // Address 0x0c |
`define RTC_RRTC_CTRL 3'h4 // Address 0x10 |
|
// |
// Default values for unimplemented RTC registers |
// |
`define RTC_DEF_RRTC_TALRM 32'h00000000 // No time alarms |
`define RTC_DEF_RRTC_DALRM 31'h00000000 // No date alarms |
`define RTC_DEF_RRTC_CTRL 32'h80000000 // RRTC_CTRL[EN] = 1 |
|
// |
// RRTC_TIME bits |
// |
// To comply with the RTC IP core specification document they must go from |
// bit 0 to bit 26 in the following order: TOS, S, TS, M, TM, H, TH, DOW |
// |
`define RTC_RRTC_TIME_TOS 3:0 |
`define RTC_RRTC_TIME_S 7:4 |
`define RTC_RRTC_TIME_TS 10:8 |
`define RTC_RRTC_TIME_M 14:11 |
`define RTC_RRTC_TIME_TM 17:15 |
`define RTC_RRTC_TIME_H 21:18 |
`define RTC_RRTC_TIME_TH 23:22 |
`define RTC_RRTC_TIME_DOW 26:24 |
|
// |
// RRTC_DATE bits |
// |
// To comply with the RTC IP core specification document they must go from |
// bit 0 to bit 26 in the following order: D, TD, M, TM, Y, TY, C, TC |
// |
`define RTC_RRTC_DATE_D 3:0 |
`define RTC_RRTC_DATE_TD 5:4 |
`define RTC_RRTC_DATE_M 9:6 |
`define RTC_RRTC_DATE_TM 10 |
`define RTC_RRTC_DATE_Y 14:11 |
`define RTC_RRTC_DATE_TY 18:15 |
`define RTC_RRTC_DATE_C 22:19 |
`define RTC_RRTC_DATE_TC 26:23 |
|
// |
// RRTC_TALRM bits |
// |
// To comply with the RTC IP core specification document they must go from |
// bit 0 to bit 31 in the following order: TOS, S, TS, M, TM, H, TH, DOW, |
// CTOS, CS, CM, CH, CDOW |
// |
`define RTC_RRTC_TALRM_TOS 3:0 |
`define RTC_RRTC_TALRM_S 7:4 |
`define RTC_RRTC_TALRM_TS 10:8 |
`define RTC_RRTC_TALRM_M 14:11 |
`define RTC_RRTC_TALRM_TM 17:15 |
`define RTC_RRTC_TALRM_H 21:18 |
`define RTC_RRTC_TALRM_TH 23:22 |
`define RTC_RRTC_TALRM_DOW 26:24 |
`define RTC_RRTC_TALRM_CTOS 27 |
`define RTC_RRTC_TALRM_CS 28 |
`define RTC_RRTC_TALRM_CM 29 |
`define RTC_RRTC_TALRM_CH 30 |
`define RTC_RRTC_TALRM_CDOW 31 |
|
// |
// RRTC_DALRM bits |
// |
// To comply with the RTC IP core specification document they must go from |
// bit 0 to bit 30 in the following order: D, TD, M, TM, Y, TY, C, TC, |
// CD, CM, CY, CC |
// |
`define RTC_RRTC_DALRM_D 3:0 |
`define RTC_RRTC_DALRM_TD 5:4 |
`define RTC_RRTC_DALRM_M 9:6 |
`define RTC_RRTC_DALRM_TM 10 |
`define RTC_RRTC_DALRM_Y 14:11 |
`define RTC_RRTC_DALRM_TY 18:15 |
`define RTC_RRTC_DALRM_C 22:19 |
`define RTC_RRTC_DALRM_TC 26:23 |
`define RTC_RRTC_DALRM_CD 27 |
`define RTC_RRTC_DALRM_CM 28 |
`define RTC_RRTC_DALRM_CY 29 |
`define RTC_RRTC_DALRM_CC 30 |
|
// |
// RRTC_CTRL bits |
// |
// To comply with the RTC IP core specification document they must go from |
// bit 0 to bit 31 in the following order: DIV, BTOS, ECLK, INTE, ALRM, EN |
// |
`define RTC_RRTC_CTRL_DIV 26:0 |
`define RTC_RRTC_CTRL_BTOS 27 |
`define RTC_RRTC_CTRL_ECLK 28 |
`define RTC_RRTC_CTRL_INTE 29 |
`define RTC_RRTC_CTRL_ALRM 30 |
`define RTC_RRTC_CTRL_EN 31 |
/trunk/rtl/verilog/rtc_top.v
0,0 → 1,676
////////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE Real-Time Clock //// |
//// //// |
//// This file is part of the RTC project //// |
//// http://www.opencores.org/cores/rtc/ //// |
//// //// |
//// Description //// |
//// Implementation of Real-Time clock IP core according to //// |
//// RTC IP core specification document. Using async resets //// |
//// would make core even smaller. //// |
//// //// |
//// 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.2 2001/08/22 10:58:27 lampret |
// Changed synthesis translate_ to synopsys translate. |
// |
// Revision 1.1 2001/08/21 12:53:11 lampret |
// Changed directory structure, uniquified defines and changed design's port names. |
// |
// Revision 1.3 2001/07/17 00:02:55 lampret |
// Fixed reading of registers. |
// |
// Revision 1.2 2001/07/16 01:08:45 lampret |
// Added additional parameters to make RTL more configurable. Added bunch of comments to defines.v |
// |
// Revision 1.1 2001/06/05 07:45:43 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 "rtc_defines.v" |
|
module rtc_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 RTC Interface |
clk_rtc_pad_i |
); |
|
parameter dw = 32; |
parameter aw = `RTC_ADDRHH+1; |
|
// |
// 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 RTC Interface |
// |
input clk_rtc_pad_i; // External clock |
|
`ifdef RTC_IMPLEMENTED |
|
// |
// Counters of RTC Time Register |
// |
reg [3:0] time_tos; // Tenth of second counter |
reg [3:0] time_s; // Seconds counter |
reg [2:0] time_ts; // Ten seconds counter |
reg [3:0] time_m; // Minutes counter |
reg [2:0] time_tm; // Ten minutes counter |
reg [3:0] time_h; // Hours counter |
reg [1:0] time_th; // Ten hours counter |
reg [2:0] time_dow; // Day of week counter |
|
// |
// Counter of RTC Date Register |
// |
reg [3:0] date_d; // Days counter |
reg [1:0] date_td; // Ten days counter |
reg [3:0] date_m; // Months counter |
reg date_tm; // Ten months counter |
reg [3:0] date_y; // Years counter |
reg [3:0] date_ty; // Ten years counter |
reg [3:0] date_c; // Centuries counter |
reg [3:0] date_tc; // Ten centuries counter |
|
// |
// Clock division counter |
// |
`ifdef RTC_DIVIDER |
reg [26:0] cntr_div; // Division counter |
reg div_clk; // Tenth of a second clock |
`else |
wire div_clk; // Tenth of a second clock |
`endif |
|
// |
// RTC TALRM Register |
// |
`ifdef RTC_RRTC_TALRM |
reg [31:0] rrtc_talrm; // RRTC_TALRM register |
`else |
wire [31:0] rrtc_talrm; // No register |
`endif |
|
// |
// RTC DALRM Register |
// |
`ifdef RTC_RRTC_DALRM |
reg [30:0] rrtc_dalrm; // RRTC_DALRM register |
`else |
wire [30:0] rrtc_dalrm; // No register |
`endif |
|
// |
// RTC CTRL register |
// |
reg [31:0] rrtc_ctrl; // RRTC_CTRL register |
|
// |
// Internal wires & regs |
// |
wire [31:0] rrtc_time; // Alias |
wire [31:0] rrtc_date; // Alias |
wire rrtc_time_sel; // RRTC_TIME select |
wire rrtc_date_sel; // RRTC_DATE select |
wire rrtc_talrm_sel; // RRTC_TALRM select |
wire rrtc_dalrm_sel; // RRTC_DALRM select |
wire rrtc_ctrl_sel; // RRTC_CTRL select |
wire match_tos; // Tenth of second match |
wire match_secs; // Seconds match |
wire match_mins; // Minutes match |
wire match_hrs; // Hours match |
wire match_dow; // Day of week match |
wire match_days; // Days match |
wire match_months; // Months match |
wire match_yrs; // Years match |
wire match_cents; // Centuries match |
wire rst_time_tos; // Reset RRTC_TIME[TOS] |
wire rst_time_s; // Reset RRTC_TIME[S] |
wire rst_time_ts; // Reset RRTC_TIME[TS] |
wire rst_time_m; // Reset RRTC_TIME[M] |
wire rst_time_tm; // Reset RRTC_TIME[TM] |
wire rst_time_h; // Reset RRTC_TIME[H] |
wire rst_time_th; // Reset RRTC_TIME[TH] |
wire rst_time_dow; // Reset RRTC_TIME[DOW] |
wire rst_date_d; // Reset RRTC_DATE[D] |
wire rst_date_td; // Reset RRTC_DATE[TD] |
wire rst_date_m; // Reset RRTC_DATE[M] |
wire rst_date_tm; // Reset RRTC_DATE[TM] |
wire rst_date_y; // Reset RRTC_DATE[Y] |
wire rst_date_ty; // Reset RRTC_DATE[TY] |
wire rst_date_c; // Reset RRTC_DATE[C] |
wire rst_date_tc; // Reset RRTC_DATE[TC] |
wire inc_time_tos; // Enable counter RRTC_TIME[TOS] |
wire inc_time_s; // Enable counter RRTC_TIME[S] |
wire inc_time_ts; // Enable counter RRTC_TIME[TS] |
wire inc_time_m; // Enable counter RRTC_TIME[M] |
wire inc_time_tm; // Enable counter RRTC_TIME[TM] |
wire inc_time_h; // Enable counter RRTC_TIME[H] |
wire inc_time_th; // Enable counter RRTC_TIME[TH] |
wire inc_time_dow; // Enable counter RRTC_TIME[DOW] |
wire inc_date_d; // Enable counter RRTC_DATE[D] |
wire inc_date_td; // Enable counter RRTC_DATE[TD] |
wire inc_date_m; // Enable counter RRTC_DATE[M] |
wire inc_date_tm; // Enable counter RRTC_DATE[TM] |
wire inc_date_y; // Enable counter RRTC_DATE[Y] |
wire inc_date_ty; // Enable counter RRTC_DATE[TY] |
wire inc_date_c; // Enable counter RRTC_DATE[C] |
wire inc_date_tc; // Enable counter RRTC_DATE[TC] |
wire one_date_d; // Set RRTC_DATE[D] to 1 |
wire one_date_m; // Set RRTC_DATE[M] to 1 |
wire hi_clk; // Hi freq clock |
wire lo_clk; // Lo freq clock |
wire alarm; // Alarm condition |
wire leapyear; // Leap year |
wire full_decoding; // Full address decoding qualification |
reg [dw-1:0] wb_dat_o; // Data out |
|
// |
// All WISHBONE transfer terminations are successful except when: |
// a) full address decoding is enabled and address doesn't match |
// any of the RTC 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 RTC_FULL_DECODE |
`ifdef RTC_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 RTC_STRICT_32BIT_ACCESS |
assign wb_err_o = (wb_sel_i != 4'b1111); |
`else |
assign wb_err_o = 1'b0; |
`endif |
`endif |
|
// |
// Hi freq clock is selected by RRTC_CTRL[ECLK]. When it is set, |
// external clock is used. |
// |
assign hi_clk = rrtc_ctrl[`RTC_RRTC_CTRL_ECLK] ? clk_rtc_pad_i : wb_clk_i; |
|
// |
// Lo freq clock divided hi freq clock when RRTC_CTRL[EN] is set. |
// When RRTC_CTRL[EN] is cleared, lo freq clock is equal WISHBONE |
// clock to allow writes into registers. |
// |
assign lo_clk = rrtc_ctrl[`RTC_RRTC_CTRL_EN] ? div_clk : wb_clk_i; |
|
// |
// Full address decoder |
// |
`ifdef RTC_FULL_DECODE |
assign full_decoding = (wb_adr_i[`RTC_ADDRHH:`RTC_ADDRHL] == {`RTC_ADDRHH-`RTC_ADDRHL+1{1'b0}}) & |
(wb_adr_i[`RTC_ADDRLH:`RTC_ADDRLL] == {`RTC_ADDRLH-`RTC_ADDRLL+1{1'b0}}); |
`else |
assign full_decoding = 1'b1; |
`endif |
|
// |
// RTC registers address decoder |
// |
assign rrtc_time_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == |
`RTC_RRTC_TIME) & full_decoding; |
assign rrtc_date_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_DATE) & full_decoding; |
assign rrtc_talrm_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_TALRM) & full_decoding; |
assign rrtc_dalrm_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_DALRM) & full_decoding; |
assign rrtc_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_CTRL) & full_decoding; |
|
// |
// Grouping of seperate fields into registers |
// |
assign rrtc_time = {5'b0, time_dow, time_th, time_h, time_tm, |
time_m, time_ts, time_s, time_tos}; |
assign rrtc_date = {5'b0, date_tc, date_c, date_ty, date_y, |
date_tm, date_m, date_td, date_d}; |
|
// |
// Write to RRTC_CTRL or update of RRTC_CTRL[ALRM] bit |
// |
`ifdef RTC_RRTC_CTRL |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rrtc_ctrl <= #1 32'b0; |
else if (rrtc_ctrl_sel && wb_we_i) |
rrtc_ctrl <= #1 wb_dat_i; |
else if (rrtc_ctrl[`RTC_RRTC_CTRL_EN]) |
rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] <= #1 rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] | alarm; |
`else |
assign rrtc_ctrl = `RTC_DEF_RRTC_CTRL; |
`endif |
|
// |
// Clock divider |
// |
`ifdef RTC_DIVIDER |
always @(posedge hi_clk or posedge wb_rst_i) |
if (wb_rst_i) begin |
cntr_div <= #1 27'b0; |
div_clk <= #1 1'b0; |
end else if (!cntr_div) begin |
cntr_div <= #1 rrtc_ctrl[`RTC_RRTC_CTRL_DIV]; |
div_clk <= #1 ~div_clk; |
end else if (rrtc_ctrl[`RTC_RRTC_CTRL_EN]) |
cntr_div <= #1 cntr_div - 1; |
`else |
assign div_clk = hi_clk; |
`endif |
|
// |
// Write to RRTC_TALRM |
// |
`ifdef RTC_RRTC_TALRM |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rrtc_talrm <= #1 32'b0; |
else if (rrtc_talrm_sel && wb_we_i) |
rrtc_talrm <= #1 wb_dat_i; |
`else |
assign rrtc_talrm = `RTC_DEF_RRTC_TALRM; |
`endif |
|
// |
// Write to RRTC_DALRM |
// |
`ifdef RTC_RRTC_DALRM |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rrtc_dalrm <= #1 31'b0; |
else if (rrtc_dalrm_sel && wb_we_i) |
rrtc_dalrm <= #1 wb_dat_i[30:0]; |
`else |
assign rrtc_dalrm = `RTC_DEF_RRTC_DALRM; |
`endif |
|
// |
// RRTC_TIME[TOS] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_tos <= #1 wb_dat_i[`RTC_RRTC_TIME_TOS]; |
else if (rst_time_tos) |
time_tos <= #1 4'b0; |
else if (inc_time_tos) |
time_tos <= #1 time_tos + 1; |
|
// |
// RRTC_TIME[S] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_s <= #1 wb_dat_i[`RTC_RRTC_TIME_S]; |
else if (rst_time_s) |
time_s <= #1 4'b0; |
else if (inc_time_s) |
time_s <= #1 time_s + 1; |
|
// |
// RRTC_TIME[TS] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_ts <= #1 wb_dat_i[`RTC_RRTC_TIME_TS]; |
else if (rst_time_ts) |
time_ts <= #1 3'b0; |
else if (inc_time_ts) |
time_ts <= #1 time_ts + 1; |
|
// |
// RRTC_TIME[M] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_m <= #1 wb_dat_i[`RTC_RRTC_TIME_M]; |
else if (rst_time_m) |
time_m <= #1 4'b0; |
else if (inc_time_m) |
time_m <= #1 time_m + 1; |
|
// |
// RRTC_TIME[TM] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_tm <= #1 wb_dat_i[`RTC_RRTC_TIME_TM]; |
else if (rst_time_tm) |
time_tm <= #1 3'b0; |
else if (inc_time_tm) |
time_tm <= #1 time_tm + 1; |
|
// |
// RRTC_TIME[H] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_h <= #1 wb_dat_i[`RTC_RRTC_TIME_H]; |
else if (rst_time_h) |
time_h <= #1 4'b0; |
else if (inc_time_h) |
time_h <= #1 time_h + 1; |
|
// |
// RRTC_TIME[TH] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_th <= #1 wb_dat_i[`RTC_RRTC_TIME_TH]; |
else if (rst_time_th) |
time_th <= #1 2'b0; |
else if (inc_time_th) |
time_th <= #1 time_th + 1; |
|
// |
// RRTC_TIME[DOW] |
// |
always @(posedge lo_clk) |
if (rrtc_time_sel && wb_we_i) |
time_dow <= #1 wb_dat_i[`RTC_RRTC_TIME_DOW]; |
else if (rst_time_dow) |
time_dow <= #1 3'h1; |
else if (inc_time_dow) |
time_dow <= #1 time_dow + 1; |
|
// |
// RRTC_DATE[D] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_d <= #1 wb_dat_i[`RTC_RRTC_DATE_D]; |
else if (one_date_d) |
date_d <= #1 4'h1; |
else if (rst_date_d) |
date_d <= #1 4'h0; |
else if (inc_date_d) |
date_d <= #1 date_d + 1; |
|
// |
// RRTC_DATE[TD] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_td <= #1 wb_dat_i[`RTC_RRTC_DATE_TD]; |
else if (rst_date_td) |
date_td <= #1 2'b0; |
else if (inc_date_td) |
date_td <= #1 date_td + 1; |
|
// |
// RRTC_DATE[M] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_m <= #1 wb_dat_i[`RTC_RRTC_DATE_M]; |
else if (one_date_m) |
date_m <= #1 4'h1; |
else if (rst_date_m) |
date_m <= #1 4'h0; |
else if (inc_date_m) |
date_m <= #1 date_m + 1; |
|
// |
// RRTC_DATE[TM] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_tm <= #1 wb_dat_i[`RTC_RRTC_DATE_TM]; |
else if (rst_date_tm) |
date_tm <= #1 1'b0; |
else if (inc_date_tm) |
date_tm <= #1 date_tm + 1; |
|
// |
// RRTC_DATE[Y] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_y <= #1 wb_dat_i[`RTC_RRTC_DATE_Y]; |
else if (rst_date_y) |
date_y <= #1 4'b0; |
else if (inc_date_y) |
date_y <= #1 date_y + 1; |
|
// |
// RRTC_DATE[TY] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_ty <= #1 wb_dat_i[`RTC_RRTC_DATE_TY]; |
else if (rst_date_ty) |
date_ty <= #1 4'b0; |
else if (inc_date_ty) |
date_ty <= #1 date_ty + 1; |
|
// |
// RRTC_DATE[C] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_c <= #1 wb_dat_i[`RTC_RRTC_DATE_C]; |
else if (rst_date_c) |
date_c <= #1 4'b0; |
else if (inc_date_c) |
date_c <= #1 date_c + 1; |
|
// |
// RRTC_DATE[TC] |
// |
always @(posedge lo_clk) |
if (rrtc_date_sel && wb_we_i) |
date_tc <= #1 wb_dat_i[`RTC_RRTC_DATE_TC]; |
else if (rst_date_tc) |
date_tc <= #1 4'b0; |
else if (inc_date_tc) |
date_tc <= #1 date_tc + 1; |
|
// |
// Read RTC registers |
// |
always @(wb_adr_i or rrtc_time or rrtc_date or rrtc_talrm or rrtc_dalrm or rrtc_ctrl) |
case (wb_adr_i[`RTC_OFS_BITS]) // synopsys full_case parallel_case |
`ifdef RTC_READREGS |
`RTC_RRTC_TIME: wb_dat_o[dw-1:0] <= {{dw-27{1'b0}}, rrtc_time}; |
`RTC_RRTC_DATE: wb_dat_o[dw-1:0] <= {{dw-27{1'b0}}, rrtc_date}; |
`RTC_RRTC_TALRM: wb_dat_o[dw-1:0] <= rrtc_talrm; |
`RTC_RRTC_DALRM: wb_dat_o[dw-1:0] <= {{dw-31{1'b0}}, rrtc_dalrm}; |
`endif |
default: wb_dat_o <= rrtc_ctrl; |
endcase |
|
// |
// Asserted high when correspoding RRTC_TIME/DATE fields match |
// RRTC_T/DALRM fields |
// |
assign match_tos = (time_tos == rrtc_talrm[`RTC_RRTC_TALRM_TOS]); |
assign match_secs = (time_s == rrtc_talrm[`RTC_RRTC_TALRM_S]) & |
(time_ts == rrtc_talrm[`RTC_RRTC_TALRM_TS]); |
assign match_mins = (time_m == rrtc_talrm[`RTC_RRTC_TALRM_M]) & |
(time_tm == rrtc_talrm[`RTC_RRTC_TALRM_TM]); |
assign match_hrs = (time_h == rrtc_talrm[`RTC_RRTC_TALRM_H]) & |
(time_th == rrtc_talrm[`RTC_RRTC_TALRM_TH]); |
assign match_dow = (time_dow == rrtc_talrm[`RTC_RRTC_TALRM_DOW]); |
assign match_days = (date_d == rrtc_dalrm[`RTC_RRTC_DALRM_D]) & |
(date_td == rrtc_dalrm[`RTC_RRTC_DALRM_TD]); |
assign match_months = (date_m == rrtc_dalrm[`RTC_RRTC_DALRM_M]) & |
(date_tm == rrtc_dalrm[`RTC_RRTC_DALRM_TM]); |
assign match_yrs = (date_y == rrtc_dalrm[`RTC_RRTC_DALRM_Y]) & |
(date_ty == rrtc_dalrm[`RTC_RRTC_DALRM_TY]); |
assign match_cents = (date_c == rrtc_dalrm[`RTC_RRTC_DALRM_C]) & |
(date_tc == rrtc_dalrm[`RTC_RRTC_DALRM_TC]); |
|
// |
// Generate an alarm when all enabled match conditions are asserted high |
// |
assign alarm = (match_tos | ~rrtc_talrm[`RTC_RRTC_TALRM_CTOS]) & |
(match_secs | ~rrtc_talrm[`RTC_RRTC_TALRM_CS]) & |
(match_mins | ~rrtc_talrm[`RTC_RRTC_TALRM_CM]) & |
(match_hrs | ~rrtc_talrm[`RTC_RRTC_TALRM_CH]) & |
(match_dow | ~rrtc_talrm[`RTC_RRTC_TALRM_CDOW]) & |
(match_days | ~rrtc_dalrm[`RTC_RRTC_DALRM_CD]) & |
(match_months | ~rrtc_dalrm[`RTC_RRTC_DALRM_CM]) & |
(match_yrs | ~rrtc_dalrm[`RTC_RRTC_DALRM_CY]) & |
(match_cents | ~rrtc_dalrm[`RTC_RRTC_DALRM_CC]) & |
(rrtc_talrm[`RTC_RRTC_TALRM_CTOS] | |
rrtc_talrm[`RTC_RRTC_TALRM_CS] | |
rrtc_talrm[`RTC_RRTC_TALRM_CM] | |
rrtc_talrm[`RTC_RRTC_TALRM_CH] | |
rrtc_talrm[`RTC_RRTC_TALRM_CDOW] | |
rrtc_dalrm[`RTC_RRTC_DALRM_CD] | |
rrtc_dalrm[`RTC_RRTC_DALRM_CM] | |
rrtc_dalrm[`RTC_RRTC_DALRM_CY] | |
rrtc_dalrm[`RTC_RRTC_DALRM_CC]); |
|
// |
// Generate an interrupt request |
// |
assign wb_inta_o = rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] & rrtc_ctrl[`RTC_RRTC_CTRL_INTE]; |
|
// |
// Control of counters: |
// Asserted high when correspoding RRTC_TIME/DATE fields reach |
// boundary values and previous counters are cleared |
// |
assign rst_time_tos = (time_tos == 4'd9) | rrtc_ctrl[`RTC_RRTC_CTRL_BTOS] | wb_rst_i; |
assign rst_time_s = (time_s == 4'd9) & rst_time_tos | wb_rst_i; |
assign rst_time_ts = (time_ts == 3'd5) & rst_time_s | wb_rst_i; |
assign rst_time_m = (time_m == 4'd9) & rst_time_ts | wb_rst_i; |
assign rst_time_tm = (time_tm == 3'd5) & rst_time_m | wb_rst_i; |
assign rst_time_h = (time_h == 4'd9) & rst_time_tm |
| (time_th == 2'd2) & (time_h == 4'd3) & rst_time_tm |
| wb_rst_i; |
assign rst_time_th = (time_th == 2'd2) & rst_time_h | wb_rst_i; |
assign rst_time_dow = (time_dow == 3'd7) & rst_time_th | wb_rst_i; |
assign one_date_d = |
({date_tm, date_m} == 8'h01 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h02 & date_td == 2'd2 & date_d == 4'd8 & ~leapyear | |
{date_tm, date_m} == 8'h02 & date_td == 2'd2 & date_d == 4'd9 & leapyear | |
{date_tm, date_m} == 8'h03 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h04 & date_td == 2'd3 & date_d == 4'd0 | |
{date_tm, date_m} == 8'h05 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h06 & date_td == 2'd3 & date_d == 4'd0 | |
{date_tm, date_m} == 8'h07 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h08 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h09 & date_td == 2'd3 & date_d == 4'd0 | |
{date_tm, date_m} == 8'h10 & date_td == 2'd3 & date_d == 4'd1 | |
{date_tm, date_m} == 8'h11 & date_td == 2'd3 & date_d == 4'd0 | |
{date_tm, date_m} == 8'h12 & date_td == 2'd3 & date_d == 4'd1 ) & rst_time_th | |
wb_rst_i; |
assign rst_date_d = date_d == 4'd9 & rst_time_th; |
assign rst_date_td = ({date_tm, date_m} == 8'h02 & date_td[1] | |
date_td == 2'h3) & (rst_date_d | one_date_d) | |
wb_rst_i; |
assign one_date_m = date_tm & (date_m == 4'd2) & rst_date_td | wb_rst_i; |
assign rst_date_m = ~date_tm & (date_m == 4'd9) & rst_date_td; |
assign rst_date_tm = date_tm & (rst_date_m | one_date_m) | wb_rst_i; |
assign rst_date_y = (date_y == 4'd9) & rst_date_tm | wb_rst_i; |
assign rst_date_ty = (date_ty == 4'd9)& rst_date_y | wb_rst_i; |
assign rst_date_c = (date_c == 4'd9) & rst_date_ty | wb_rst_i; |
assign rst_date_tc = (date_tc == 4'd9) & rst_date_c | wb_rst_i; |
|
// |
// Control for counter increment |
// |
assign inc_time_tos = rrtc_ctrl[`RTC_RRTC_CTRL_EN] & ~rrtc_ctrl[`RTC_RRTC_CTRL_BTOS]; |
assign inc_time_s = rst_time_tos | rrtc_ctrl[`RTC_RRTC_CTRL_BTOS] & rrtc_ctrl[`RTC_RRTC_CTRL_EN]; |
assign inc_time_ts = rst_time_s; |
assign inc_time_m = rst_time_ts; |
assign inc_time_tm = rst_time_m; |
assign inc_time_h = rst_time_tm; |
assign inc_time_th = rst_time_h; |
assign inc_time_dow = rst_time_th; |
assign inc_date_d = rst_time_th; |
assign inc_date_td = rst_date_d; |
assign inc_date_m = rst_date_td; |
assign inc_date_tm = rst_date_m; |
assign inc_date_y = rst_date_tm; |
assign inc_date_ty = rst_date_y; |
assign inc_date_c = rst_date_ty; |
assign inc_date_tc = rst_date_c; |
|
// |
// Leap year calculation |
// |
assign leapyear = |
(({date_ty, date_y} == 8'h00) & // xx00 |
(( date_tc[0] & ~date_c[3] & (date_c[1:0] == 2'b10)) | // 12xx, 16xx, 32xx ... |
(~date_tc[0] & (date_c[1:0] == 2'b00) & // 00xx, 04xx, 08xx, 20xx, 24xx ... |
((date_c[3:2] == 2'b01) | ~date_c[2])))) | |
(~date_ty[0] & (date_y[1:0] == 2'b00) & ({date_ty, date_y} != 8'h00)) | // xx04, xx08, xx24 ... |
(date_ty[0] & (date_y[1:0] == 2'b10)); // xx12, xx16, xx32 ... |
|
|
`else |
|
// |
// When RTC is not implemented, drive all outputs as would when RRTC_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 = wb_cyc_i & wb_stb_i; |
|
// |
// Read RTC registers |
// |
assign wb_dat_o = {dw{1'b0}}; |
|
`endif |
|
endmodule |
/trunk/sim/rtl_sim/bin/sim.sh
12,7 → 12,7
# |
|
# Set simulation tool you are using (xl, ncsim, ncver) |
SIMTOOL=ncver |
SIMTOOL=ncsim |
|
# Set test bench top module(s) |
TB_TOP="tb_tasks" |