183 lines
5.3 KiB
Verilog
183 lines
5.3 KiB
Verilog
`timescale 1ns / 1ps
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Company:
|
|
// Engineer:
|
|
//
|
|
// Create Date: 13:33:14 02/09/2011
|
|
// Design Name:
|
|
// Module Name: srtc
|
|
// Project Name:
|
|
// Target Devices:
|
|
// Tool versions:
|
|
// Description:
|
|
//
|
|
// Dependencies:
|
|
//
|
|
// Revision:
|
|
// Revision 0.01 - File Created
|
|
// Additional Comments:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
module srtc(
|
|
input clkin,
|
|
input addr_in,
|
|
input [3:0] data_in,
|
|
output [7:0] data_out,
|
|
input [59:0] rtc_data_in,
|
|
output [59:0] rtc_data_out,
|
|
input reg_we,
|
|
input reg_oe,
|
|
input enable,
|
|
output rtc_we,
|
|
input reset
|
|
);
|
|
|
|
reg [59:0] rtc_data_r;
|
|
reg [59:0] rtc_data_out_r;
|
|
assign rtc_data_out = rtc_data_out_r;
|
|
|
|
reg [3:0] rtc_ptr;
|
|
|
|
reg [7:0] data_out_r;
|
|
reg [4:0] mode_r;
|
|
reg rtc_we_r;
|
|
assign rtc_we = rtc_we_r;
|
|
assign data_out = data_out_r;
|
|
|
|
reg [3:0] reg_oe_sreg;
|
|
always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[2:0], reg_oe};
|
|
wire reg_oe_falling = (reg_oe_sreg == 4'b1000);
|
|
|
|
reg [1:0] reg_we_sreg;
|
|
always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we};
|
|
wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01);
|
|
|
|
reg [1:0] reset_sreg;
|
|
always @(posedge clkin) reset_sreg <= {reset_sreg[0], reset};
|
|
wire reset_rising = (reset_sreg[1:0] == 2'b01);
|
|
|
|
reg[2:0] we_countdown_r;
|
|
|
|
parameter SRTC_IDLE = 5'b00001;
|
|
parameter SRTC_READ = 5'b00010;
|
|
parameter SRTC_COMMAND = 5'b00100;
|
|
parameter SRTC_WRITE = 5'b01000;
|
|
parameter SRTC_WRITE2 = 5'b10000;
|
|
|
|
initial begin
|
|
rtc_we_r = 0;
|
|
mode_r <= SRTC_READ;
|
|
rtc_ptr <= 4'hf;
|
|
end
|
|
|
|
always @(posedge clkin) begin
|
|
if(reset_rising) begin
|
|
mode_r <= SRTC_READ;
|
|
rtc_ptr <= 4'hf;
|
|
end else if(mode_r == SRTC_WRITE2) begin
|
|
we_countdown_r <= we_countdown_r - 1;
|
|
if (we_countdown_r == 3'b000) begin
|
|
mode_r <= SRTC_WRITE;
|
|
rtc_we_r <= 0;
|
|
end
|
|
end else if(reg_we_rising && enable) begin
|
|
case (addr_in)
|
|
// 1'b0: // data register is read only
|
|
1'b1: // control register
|
|
case (data_in)
|
|
4'hd: begin
|
|
mode_r <= SRTC_READ;
|
|
rtc_ptr <= 4'hf;
|
|
end
|
|
4'he: begin
|
|
mode_r <= SRTC_COMMAND;
|
|
end
|
|
4'hf: begin
|
|
end
|
|
default: begin
|
|
if(mode_r == SRTC_COMMAND) begin
|
|
case (data_in)
|
|
4'h0: begin
|
|
mode_r <= SRTC_WRITE;
|
|
rtc_data_out_r <= rtc_data_in;
|
|
rtc_ptr <= 4'h0;
|
|
end
|
|
4'h4: begin
|
|
mode_r <= SRTC_IDLE;
|
|
rtc_ptr <= 4'hf;
|
|
end
|
|
default:
|
|
mode_r <= SRTC_IDLE;
|
|
endcase
|
|
end else if(mode_r == SRTC_WRITE) begin
|
|
rtc_ptr <= rtc_ptr + 1;
|
|
case(rtc_ptr)
|
|
0: rtc_data_out_r[3:0] <= data_in;
|
|
1: rtc_data_out_r[7:4] <= data_in;
|
|
2: rtc_data_out_r[11:8] <= data_in;
|
|
3: rtc_data_out_r[15:12] <= data_in;
|
|
4: rtc_data_out_r[19:16] <= data_in;
|
|
5: rtc_data_out_r[23:20] <= data_in;
|
|
6: rtc_data_out_r[27:24] <= data_in;
|
|
7: rtc_data_out_r[31:28] <= data_in;
|
|
8: begin
|
|
rtc_data_out_r[35:32] <= (data_in < 10)
|
|
? data_in
|
|
: data_in - 10;
|
|
rtc_data_out_r[39:36] <= data_in < 10 ? 0 : 1;
|
|
end
|
|
9: rtc_data_out_r[43:40] <= data_in;
|
|
10: rtc_data_out_r[47:44] <= data_in;
|
|
11: begin
|
|
rtc_data_out_r[51:48] <= (data_in < 10)
|
|
? data_in
|
|
: data_in - 10;
|
|
rtc_data_out_r[55:52] <= data_in < 10 ? 1 : 2;
|
|
end
|
|
endcase
|
|
mode_r <= SRTC_WRITE2;
|
|
we_countdown_r <= 5;
|
|
rtc_we_r <= 1;
|
|
end
|
|
end
|
|
endcase
|
|
endcase
|
|
end else if(reg_oe_falling && enable) begin
|
|
case (addr_in)
|
|
1'b0: // read data register
|
|
if(mode_r == SRTC_READ) begin
|
|
case(rtc_ptr)
|
|
0: data_out_r <= rtc_data_r[3:0];
|
|
1: data_out_r <= rtc_data_r[7:4];
|
|
2: data_out_r <= rtc_data_r[11:8];
|
|
3: data_out_r <= rtc_data_r[15:12];
|
|
4: data_out_r <= rtc_data_r[19:16];
|
|
5: data_out_r <= rtc_data_r[23:20];
|
|
6: data_out_r <= rtc_data_r[27:24];
|
|
7: data_out_r <= rtc_data_r[31:28];
|
|
8: data_out_r <= rtc_data_r[35:32]
|
|
+ (rtc_data_r[39:36] << 1)
|
|
+ (rtc_data_r[39:36] << 3);
|
|
9: data_out_r <= rtc_data_r[43:40];
|
|
10: data_out_r <= rtc_data_r[47:44];
|
|
11: data_out_r <= rtc_data_r[51:48]
|
|
+ (rtc_data_r[55:52] << 1)
|
|
+ (rtc_data_r[55:52] << 3) - 10;
|
|
12: data_out_r <= rtc_data_r[59:56];
|
|
15: begin
|
|
rtc_data_r <= rtc_data_in;
|
|
data_out_r <= 8'h0f;
|
|
end
|
|
default: data_out_r <= 8'h0f;
|
|
endcase
|
|
rtc_ptr <= rtc_ptr == 13 ? 15 : rtc_ptr + 1;
|
|
end else begin
|
|
data_out_r <= 8'h00;
|
|
end
|
|
// 1'b1: // control register is write only
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|