mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-18 14:51:25 +03:00
RTC: cleanup.
This commit is contained in:
@ -367,8 +367,7 @@ set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
|
||||
set_global_assignment -name VERILOG_FILE src/cpu/zmaps.v
|
||||
set_global_assignment -name VERILOG_FILE src/cpu/zint.v
|
||||
set_global_assignment -name VERILOG_FILE src/cpu/zclock.v
|
||||
set_global_assignment -name VHDL_FILE src/rtc/CMOS.vhd
|
||||
set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd
|
||||
set_global_assignment -name VERILOG_FILE src/rtc/mc146818a.v
|
||||
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
|
||||
set_global_assignment -name QIP_FILE src/sound/jt12/jt12.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/ym2149.sv
|
||||
|
235
src/rtc/CMOS.vhd
235
src/rtc/CMOS.vhd
@ -1,235 +0,0 @@
|
||||
-- megafunction wizard: %RAM: 2-PORT%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: altsyncram
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: CMOS.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- altsyncram
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 11.0 Build 157 04/27/2011 SJ Full Version
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2011 Altera Corporation
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, Altera MegaCore Function License
|
||||
--Agreement, or other applicable license agreement, including,
|
||||
--without limitation, that your use is for the sole purpose of
|
||||
--programming logic devices manufactured by Altera and sold by
|
||||
--Altera or its authorized distributors. Please refer to the
|
||||
--applicable agreement for further details.
|
||||
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY CMOS IS
|
||||
PORT
|
||||
(
|
||||
clock : IN STD_LOGIC := '1';
|
||||
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
rdaddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
wraddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
wren : IN STD_LOGIC := '0';
|
||||
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
|
||||
);
|
||||
END CMOS;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF cmos IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT altsyncram
|
||||
GENERIC (
|
||||
address_aclr_b : STRING;
|
||||
address_reg_b : STRING;
|
||||
clock_enable_input_a : STRING;
|
||||
clock_enable_input_b : STRING;
|
||||
clock_enable_output_b : STRING;
|
||||
init_file : STRING;
|
||||
intended_device_family : STRING;
|
||||
lpm_type : STRING;
|
||||
numwords_a : NATURAL;
|
||||
numwords_b : NATURAL;
|
||||
operation_mode : STRING;
|
||||
outdata_aclr_b : STRING;
|
||||
outdata_reg_b : STRING;
|
||||
power_up_uninitialized : STRING;
|
||||
read_during_write_mode_mixed_ports : STRING;
|
||||
widthad_a : NATURAL;
|
||||
widthad_b : NATURAL;
|
||||
width_a : NATURAL;
|
||||
width_b : NATURAL;
|
||||
width_byteena_a : NATURAL
|
||||
);
|
||||
PORT (
|
||||
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
clock0 : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||||
wren_a : IN STD_LOGIC ;
|
||||
address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
q <= sub_wire0(7 DOWNTO 0);
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
address_aclr_b => "NONE",
|
||||
address_reg_b => "CLOCK0",
|
||||
clock_enable_input_a => "BYPASS",
|
||||
clock_enable_input_b => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
init_file => "src/rtc/CMOS.mif",
|
||||
intended_device_family => "Cyclone IV E",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 256,
|
||||
numwords_b => 256,
|
||||
operation_mode => "DUAL_PORT",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_b => "UNREGISTERED",
|
||||
power_up_uninitialized => "FALSE",
|
||||
read_during_write_mode_mixed_ports => "DONT_CARE",
|
||||
widthad_a => 8,
|
||||
widthad_b => 8,
|
||||
width_a => 8,
|
||||
width_b => 8,
|
||||
width_byteena_a => 1
|
||||
)
|
||||
PORT MAP (
|
||||
address_a => wraddress,
|
||||
clock0 => clock,
|
||||
data_a => data,
|
||||
wren_a => wren,
|
||||
address_b => rdaddress,
|
||||
q_b => sub_wire0
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ECC NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
|
||||
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "2048"
|
||||
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MIFfilename STRING "./src/rtc/CMOS.mif"
|
||||
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: enable NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: INIT_FILE STRING "./src/rtc/CMOS.mif"
|
||||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256"
|
||||
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
|
||||
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8"
|
||||
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||||
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
|
||||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
|
||||
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
|
||||
-- Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]"
|
||||
-- Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]"
|
||||
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
|
||||
-- Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0
|
||||
-- Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0
|
||||
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
|
||||
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
-- Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.cmp FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.bsf FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS_inst.vhd FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
248
src/rtc/mc146818a.v
Normal file
248
src/rtc/mc146818a.v
Normal file
@ -0,0 +1,248 @@
|
||||
//-----------------------------------------------------------------[18.10.2014]
|
||||
// MC146818A REAL-TIME CLOCK PLUS RAM
|
||||
//-----------------------------------------------------------------------------
|
||||
// V0.1 05.10.2011 Initial version
|
||||
// V0.2 06.09.2014 Added General Purpose RAM
|
||||
|
||||
module mc146818a
|
||||
(
|
||||
input RESET,
|
||||
input CLK,
|
||||
input ENA,
|
||||
input CS,
|
||||
|
||||
input [64:0] RTC,
|
||||
input [31:0] CMOSCfg,
|
||||
|
||||
input [7:0] KEYSCANCODE,
|
||||
input WR,
|
||||
input [7:0] A,
|
||||
input [7:0] DI,
|
||||
output [7:0] DO
|
||||
);
|
||||
|
||||
reg [18:0] pre_scaler =0;
|
||||
reg [1:0] leap_reg =0;
|
||||
reg [7:0] seconds_reg =0; // 00
|
||||
reg [7:0] seconds_alarm_reg =0; // 01
|
||||
reg [7:0] minutes_reg =0; // 02
|
||||
reg [7:0] minutes_alarm_reg = 0;// 03
|
||||
reg [7:0] hours_reg =0; // 04
|
||||
reg [7:0] hours_alarm_reg ='hff;// 05
|
||||
reg [7:0] weeks_reg = 1; // 06
|
||||
reg [7:0] days_reg = 1; // 07
|
||||
reg [7:0] month_reg = 1; // 08
|
||||
reg [7:0] year_reg = 0; // 09
|
||||
reg [7:0] a_reg; // 0A
|
||||
reg [7:0] b_reg = 8'b00000010; // 0B
|
||||
reg [7:0] c_reg; // 0C
|
||||
|
||||
wire [7:0] CMOS_Dout;
|
||||
reg [7:0] Dout;
|
||||
|
||||
assign DO = Dout;
|
||||
|
||||
always @(*) begin
|
||||
case (A[7:0])
|
||||
8'h00 : Dout <= seconds_reg;
|
||||
8'h01 : Dout <= seconds_alarm_reg;
|
||||
8'h02 : Dout <= minutes_reg;
|
||||
8'h03 : Dout <= minutes_alarm_reg;
|
||||
8'h04 : Dout <= hours_reg;
|
||||
8'h05 : Dout <= hours_alarm_reg;
|
||||
8'h06 : Dout <= weeks_reg;
|
||||
8'h07 : Dout <= days_reg;
|
||||
8'h08 : Dout <= month_reg;
|
||||
8'h09 : Dout <= year_reg;
|
||||
8'h0a : Dout <= a_reg;
|
||||
8'h0b : Dout <= b_reg;
|
||||
8'h0c : Dout <= c_reg;
|
||||
8'h0d : Dout <= 8'b10000000;
|
||||
|
||||
8'hb1 : Dout <= CMOSCfg[7:6]; // CPU Speed
|
||||
8'hb2 : Dout <= 0; // Boot device
|
||||
8'hb3 : Dout <= CMOSCfg[8]; // CPU Cache
|
||||
8'hb4 : Dout <= CMOSCfg[13:11]; // F11
|
||||
8'hb5 : Dout <= CMOSCfg[15:14]; // F11 bank
|
||||
8'hb6 : Dout <= CMOSCfg[18:16]; // Shift+F11
|
||||
8'hb7 : Dout <= CMOSCfg[20:19]; // Shift+F11 bank
|
||||
8'hb8 : Dout <= CMOSCfg[10:9]; // #7FFD
|
||||
8'hb9 : Dout <= CMOSCfg[23:21]; // ZX Palette
|
||||
8'hba : Dout <= CMOSCfg[24]; // NGS Reset
|
||||
8'hbb : Dout <= CMOSCfg[27:25]; // INT offset
|
||||
|
||||
8'hf0 : Dout <= KEYSCANCODE;
|
||||
default: Dout <= CMOS_Dout;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
reg flg;
|
||||
|
||||
flg <= RTC[64];
|
||||
if (flg != RTC[64]) begin
|
||||
seconds_reg <= RTC[7:0];
|
||||
minutes_reg <= RTC[15:8];
|
||||
hours_reg <= RTC[23:16];
|
||||
days_reg <= RTC[31:24];
|
||||
month_reg <= RTC[39:32];
|
||||
year_reg <= RTC[47:40];
|
||||
weeks_reg <= RTC[55:48] + 1'b1;
|
||||
b_reg <= 8'b00000010;
|
||||
end
|
||||
|
||||
if (RESET) b_reg <= 8'b00000010;
|
||||
else if (WR & CS) begin
|
||||
/*
|
||||
case (A[7:0])
|
||||
0 : seconds_reg <= DI;
|
||||
1 : seconds_alarm_reg <= DI;
|
||||
2 : minutes_reg <= DI;
|
||||
3 : minutes_alarm_reg <= DI;
|
||||
4 : hours_reg <= DI;
|
||||
5 : hours_alarm_reg <= DI;
|
||||
6 : weeks_reg <= DI;
|
||||
7 : days_reg <= DI;
|
||||
8 : month_reg <= DI;
|
||||
9 : year_reg <= DI;
|
||||
11 : begin
|
||||
b_reg <= DI;
|
||||
if (b_reg[2] == 1'b0) begin // BCD to BIN convertion
|
||||
if (DI[4] == 1'b0) leap_reg <= DI[1:0];
|
||||
else leap_reg <= {~DI[1], DI[0]};
|
||||
end
|
||||
else begin
|
||||
leap_reg <= DI[1:0];
|
||||
end
|
||||
end
|
||||
endcase
|
||||
*/
|
||||
end
|
||||
|
||||
if (RESET) begin
|
||||
a_reg <= 8'b00100110;
|
||||
c_reg <= 0;
|
||||
end
|
||||
else if (~b_reg[7] & ENA) begin
|
||||
if (pre_scaler) begin
|
||||
pre_scaler <= pre_scaler - 1'd1;
|
||||
a_reg[7] <= 0;
|
||||
end
|
||||
else begin
|
||||
pre_scaler <= 437500; //(0.4375MHz)
|
||||
a_reg[7] <= 1;
|
||||
c_reg[4] <= 1;
|
||||
// alarm
|
||||
if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1;
|
||||
|
||||
if (~b_reg[2]) begin
|
||||
// DM binary-coded-decimal (BCD) data mode
|
||||
if (seconds_reg[3:0] != 9) seconds_reg[3:0] <= seconds_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
seconds_reg[3:0] <= 0;
|
||||
if (seconds_reg[6:4] != 5) seconds_reg[6:4] <= seconds_reg[6:4] + 1'd1;
|
||||
else begin
|
||||
seconds_reg[6:4] <= 0;
|
||||
if (minutes_reg[3:0] != 9) minutes_reg[3:0] <= minutes_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
minutes_reg[3:0] <= 0;
|
||||
if (minutes_reg[6:4] != 5) minutes_reg[6:4] <= minutes_reg[6:4] + 1'd1;
|
||||
else begin
|
||||
minutes_reg[6:4] <= 0;
|
||||
if (hours_reg[3:0] == 9) begin
|
||||
hours_reg[3:0] <= 0;
|
||||
hours_reg[5:4] <= hours_reg[5:4] + 1'd1;
|
||||
end
|
||||
else if ({b_reg[1], hours_reg[7], hours_reg[4:0]} == 7'b0010010) begin
|
||||
hours_reg[4:0] <= 1;
|
||||
hours_reg[7] <= ~hours_reg[7];
|
||||
end
|
||||
else if (({b_reg[1], hours_reg[7], hours_reg[4:0]} != 7'b0110010) &&
|
||||
({b_reg[1], hours_reg[5:0]} != 7'b1100011)) hours_reg[3:0] <= hours_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
if (~b_reg[1]) hours_reg[7:0] <= 1;
|
||||
else hours_reg[5:0] <= 0;
|
||||
|
||||
if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1;
|
||||
else weeks_reg[2:0] <= 1;
|
||||
|
||||
if (({month_reg, days_reg, leap_reg} == {16'h0228, 2'b01}) ||
|
||||
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) ||
|
||||
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) ||
|
||||
({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) ||
|
||||
({month_reg, days_reg} == 16'h0430) ||
|
||||
({month_reg, days_reg} == 16'h0630) ||
|
||||
({month_reg, days_reg} == 16'h0930) ||
|
||||
({month_reg, days_reg} == 16'h1130) ||
|
||||
(days_reg == 8'h31)) begin
|
||||
|
||||
days_reg[5:0] <= 1;
|
||||
if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10;
|
||||
else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
month_reg[4:0] <= 1;
|
||||
leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
|
||||
if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
year_reg[3:0] <= 0;
|
||||
if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1;
|
||||
else year_reg[7:4] <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1;
|
||||
else begin
|
||||
days_reg[3:0] <= 0;
|
||||
days_reg[5:4] <= days_reg[5:4] + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
// DM binary data mode
|
||||
if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1;
|
||||
else begin
|
||||
seconds_reg <= 0;
|
||||
if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1;
|
||||
else begin
|
||||
minutes_reg <= 0;
|
||||
if ({b_reg[1], hours_reg[7], hours_reg[3:0]} == 6'b001100) hours_reg[7:0] <= 8'b10000001;
|
||||
else if (({b_reg[1], hours_reg[7], hours_reg[3:0]} != 6'b011100) & ({b_reg[1], hours_reg[4:0]} != 6'b110111)) hours_reg[4:0] <= hours_reg[4:0] + 1'd1;
|
||||
else begin
|
||||
if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1;
|
||||
else hours_reg <= 0;
|
||||
|
||||
if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1;
|
||||
else weeks_reg <= 1; // Sunday = 1
|
||||
|
||||
if (({month_reg, days_reg, leap_reg} == {16'h021C, 2'b01}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b10}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b11}) | ({month_reg, days_reg, leap_reg} == {16'h021D, 2'b00}) | ({month_reg, days_reg} == 16'h041E) | ({month_reg, days_reg} == 16'h061E) | ({month_reg, days_reg} == 16'h091E) | ({month_reg, days_reg} == 16'h0B1E) | (days_reg == 8'h1F)) begin
|
||||
days_reg <= 1;
|
||||
if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1;
|
||||
else begin
|
||||
month_reg <= 1;
|
||||
leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
|
||||
if (year_reg != 8'h63) year_reg <= year_reg + 1'd1;
|
||||
else year_reg <= 0;
|
||||
end
|
||||
end else days_reg <= days_reg + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// 50 Bytes of General Purpose RAM
|
||||
dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("src/rtc/CMOS.mif")) CMOS
|
||||
(
|
||||
.clock (CLK),
|
||||
.address_a (A),
|
||||
.data_a (DI),
|
||||
.wren_a (WR & CS),
|
||||
.q_a (CMOS_Dout)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,302 +0,0 @@
|
||||
-------------------------------------------------------------------[18.10.2014]
|
||||
-- MC146818A REAL-TIME CLOCK PLUS RAM
|
||||
-------------------------------------------------------------------------------
|
||||
-- V0.1 05.10.2011 Initial version
|
||||
-- V0.2 06.09.2014 Added General Purpose RAM
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use IEEE.std_logic_unsigned.all;
|
||||
|
||||
entity mc146818a is
|
||||
port (
|
||||
RESET : in std_logic;
|
||||
CLK : in std_logic;
|
||||
ENA : in std_logic;
|
||||
CS : in std_logic;
|
||||
|
||||
RTC : in std_logic_vector(64 downto 0);
|
||||
CMOSCfg : in std_logic_vector(31 downto 0);
|
||||
|
||||
|
||||
KEYSCANCODE : in std_logic_vector(7 downto 0);
|
||||
WR : in std_logic;
|
||||
A : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0));
|
||||
end;
|
||||
|
||||
architecture rtl of mc146818a is
|
||||
signal pre_scaler : std_logic_vector(18 downto 0);
|
||||
signal leap_reg : std_logic_vector(1 downto 0);
|
||||
signal seconds_reg : std_logic_vector(7 downto 0); -- 00
|
||||
signal seconds_alarm_reg : std_logic_vector(7 downto 0); -- 01
|
||||
signal minutes_reg : std_logic_vector(7 downto 0); -- 02
|
||||
signal minutes_alarm_reg : std_logic_vector(7 downto 0); -- 03
|
||||
signal hours_reg : std_logic_vector(7 downto 0); -- 04
|
||||
signal hours_alarm_reg : std_logic_vector(7 downto 0); -- 05
|
||||
signal weeks_reg : std_logic_vector(7 downto 0); -- 06
|
||||
signal days_reg : std_logic_vector(7 downto 0); -- 07
|
||||
signal month_reg : std_logic_vector(7 downto 0); -- 08
|
||||
signal year_reg : std_logic_vector(7 downto 0); -- 09
|
||||
signal a_reg : std_logic_vector(7 downto 0); -- 0A
|
||||
signal b_reg : std_logic_vector(7 downto 0); -- 0B
|
||||
signal c_reg : std_logic_vector(7 downto 0); -- 0C
|
||||
|
||||
signal CMOS_Dout : std_logic_vector(7 downto 0);
|
||||
signal Dout : std_logic_vector(7 downto 0);
|
||||
|
||||
|
||||
begin
|
||||
DO <= Dout;
|
||||
|
||||
process(CLK, A, seconds_reg, seconds_alarm_reg, minutes_reg, minutes_alarm_reg, hours_reg, hours_alarm_reg, weeks_reg, days_reg, month_reg, year_reg, KEYSCANCODE, CMOS_Dout, a_reg, b_reg, c_reg, CMOSCfg)
|
||||
begin
|
||||
-- 14 Bytes of Clock and Control Registers Read
|
||||
case A(7 downto 0) is
|
||||
when x"00" => Dout <= seconds_reg;
|
||||
-- when x"01" => Dout <= seconds_alarm_reg;
|
||||
when x"02" => Dout <= minutes_reg;
|
||||
-- when x"03" => Dout <= minutes_alarm_reg;
|
||||
when x"04" => Dout <= hours_reg;
|
||||
-- when x"05" => Dout <= hours_alarm_reg;
|
||||
when x"06" => Dout <= weeks_reg;
|
||||
when x"07" => Dout <= days_reg;
|
||||
when x"08" => Dout <= month_reg;
|
||||
when x"09" => Dout <= year_reg;
|
||||
when x"0a" => Dout <= a_reg;
|
||||
when x"0b" => Dout <= b_reg;
|
||||
when x"0c" => Dout <= c_reg;
|
||||
when x"0d" => Dout <= "10000000";
|
||||
|
||||
when x"b1" => Dout <= "000000" & CMOSCfg(7 downto 6); -- CPU Speed
|
||||
when x"b2" => Dout <= "00000000"; -- Boot device
|
||||
when x"b3" => Dout <= "0000000" & CMOSCfg(8); -- CPU Cache
|
||||
|
||||
when x"b4" => Dout <= "00000" & CMOSCfg(13 downto 11); -- F11
|
||||
when x"b5" => Dout <= "000000" & CMOSCfg(15 downto 14); -- F11 bank
|
||||
when x"b6" => Dout <= "00000" & CMOSCfg(18 downto 16); -- Shift+F11
|
||||
when x"b7" => Dout <= "000000" & CMOSCfg(20 downto 19); -- Shift+F11 bank
|
||||
|
||||
when x"b8" => Dout <= "000000" & CMOSCfg(10 downto 9); -- #7FFD
|
||||
when x"b9" => Dout <= "00000" & CMOSCfg(23 downto 21); -- ZX Palette
|
||||
when x"ba" => Dout <= "0000000" & CMOSCfg(24); -- NGS Reset
|
||||
when x"bb" => Dout <= "00000" & CMOSCfg(27 downto 25); -- INT offset
|
||||
|
||||
when x"f0" => Dout <= KEYSCANCODE;
|
||||
when others => Dout <= CMOS_Dout;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
process(CLK)
|
||||
variable flg : std_logic := '0';
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if flg /= RTC(64) then
|
||||
seconds_reg <= RTC(7 downto 0);
|
||||
minutes_reg <= RTC(15 downto 8);
|
||||
hours_reg <= RTC(23 downto 16);
|
||||
days_reg <= RTC(31 downto 24);
|
||||
month_reg <= RTC(39 downto 32);
|
||||
year_reg <= RTC(47 downto 40);
|
||||
weeks_reg <= RTC(55 downto 48) + "1";
|
||||
b_reg <= "00000010";
|
||||
end if;
|
||||
|
||||
flg := RTC(64);
|
||||
-- if RESET = '1' then
|
||||
-- b_reg <= "00000010";
|
||||
-- elsif WR = '1' and CS = '1' then
|
||||
-- case A(7 downto 0) is
|
||||
-- when x"00" => seconds_reg <= DI;
|
||||
-- when x"01" => seconds_alarm_reg <= DI;
|
||||
-- when x"02" => minutes_reg <= DI;
|
||||
-- when x"03" => minutes_alarm_reg <= DI;
|
||||
-- when x"04" => hours_reg <= DI;
|
||||
-- when x"05" => hours_alarm_reg <= DI;
|
||||
-- when x"06" => weeks_reg <= DI;
|
||||
-- when x"07" => days_reg <= DI;
|
||||
-- when x"08" => month_reg <= DI;
|
||||
-- when x"09" => year_reg <= DI;
|
||||
-- when x"0b" => b_reg <= DI;
|
||||
--
|
||||
-- if b_reg(2) = '0' then -- BCD to BIN convertion
|
||||
-- if DI(4) = '0' then
|
||||
-- leap_reg <= DI(1 downto 0);
|
||||
-- else
|
||||
-- leap_reg <= (not DI(1)) & DI(0);
|
||||
-- end if;
|
||||
-- else
|
||||
-- leap_reg <= DI(1 downto 0);
|
||||
-- end if;
|
||||
--
|
||||
-- when others => null;
|
||||
-- end case;
|
||||
-- end if;
|
||||
|
||||
if RESET = '1' then
|
||||
a_reg <= "00100110";
|
||||
c_reg <= (others => '0');
|
||||
elsif b_reg(7) = '0' and ENA = '1' then
|
||||
if pre_scaler /= X"000000" then
|
||||
pre_scaler <= pre_scaler - 1;
|
||||
a_reg(7) <= '0';
|
||||
else
|
||||
pre_scaler <= "1101010110011111100"; --(0.4375MHz)
|
||||
a_reg(7) <= '1';
|
||||
c_reg(4) <= '1';
|
||||
-- alarm
|
||||
-- if ((seconds_reg = seconds_alarm_reg) and
|
||||
-- (minutes_reg = minutes_alarm_reg) and
|
||||
-- (hours_reg = hours_alarm_reg)) then
|
||||
-- c_reg(5) <= '1';
|
||||
-- end if;
|
||||
-- DM binary-coded-decimal (BCD) data mode
|
||||
--if b_reg(2) = '0' then
|
||||
if seconds_reg(3 downto 0) /= "1001" then
|
||||
seconds_reg(3 downto 0) <= seconds_reg(3 downto 0) + 1;
|
||||
else
|
||||
seconds_reg(3 downto 0) <= (others => '0');
|
||||
if seconds_reg(6 downto 4) /= "101" then
|
||||
seconds_reg(6 downto 4) <= seconds_reg(6 downto 4) + 1;
|
||||
else
|
||||
seconds_reg(6 downto 4) <= (others => '0');
|
||||
if minutes_reg(3 downto 0) /= "1001" then
|
||||
minutes_reg(3 downto 0) <= minutes_reg(3 downto 0) + 1;
|
||||
else
|
||||
minutes_reg(3 downto 0) <= (others => '0');
|
||||
if minutes_reg(6 downto 4) /= "101" then
|
||||
minutes_reg(6 downto 4) <= minutes_reg(6 downto 4) + 1;
|
||||
else
|
||||
minutes_reg(6 downto 4) <= (others => '0');
|
||||
if hours_reg(3 downto 0) = "1001" then
|
||||
hours_reg(3 downto 0) <= (others => '0');
|
||||
hours_reg(5 downto 4) <= hours_reg(5 downto 4) + 1;
|
||||
elsif b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) = "0010010" then
|
||||
hours_reg(4 downto 0) <= "00001";
|
||||
hours_reg(7) <= not hours_reg(7);
|
||||
elsif ((b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) /= "0110010") and
|
||||
(b_reg(1) & hours_reg(5 downto 0) /= "1100011")) then
|
||||
hours_reg(3 downto 0) <= hours_reg(3 downto 0) + 1;
|
||||
else
|
||||
if b_reg(1) = '0' then
|
||||
hours_reg(7 downto 0) <= "00000001";
|
||||
else
|
||||
hours_reg(5 downto 0) <= (others => '0');
|
||||
end if;
|
||||
if weeks_reg(2 downto 0) /= "111" then
|
||||
weeks_reg(2 downto 0) <= weeks_reg(2 downto 0) + 1;
|
||||
else
|
||||
weeks_reg(2 downto 0) <= "001";
|
||||
end if;
|
||||
if ((month_reg & days_reg & leap_reg = X"0228" & "01") or
|
||||
(month_reg & days_reg & leap_reg = X"0228" & "10") or
|
||||
(month_reg & days_reg & leap_reg = X"0228" & "11") or
|
||||
(month_reg & days_reg & leap_reg = X"0229" & "00") or
|
||||
(month_reg & days_reg = X"0430") or
|
||||
(month_reg & days_reg = X"0630") or
|
||||
(month_reg & days_reg = X"0930") or
|
||||
(month_reg & days_reg = X"1130") or
|
||||
( days_reg = X"31")) then
|
||||
days_reg(5 downto 0) <= "000001";
|
||||
if month_reg(3 downto 0) = "1001" then
|
||||
month_reg(4 downto 0) <= "10000";
|
||||
elsif month_reg(4 downto 0) /= "10010" then
|
||||
month_reg(3 downto 0) <= month_reg(3 downto 0) + 1;
|
||||
else
|
||||
month_reg(4 downto 0) <= "00001";
|
||||
leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1;
|
||||
if year_reg(3 downto 0) /= "1001" then
|
||||
year_reg(3 downto 0) <= year_reg(3 downto 0) + 1;
|
||||
else
|
||||
year_reg(3 downto 0) <= "0000";
|
||||
if year_reg(7 downto 4) /= "1001" then
|
||||
year_reg(7 downto 4) <= year_reg(7 downto 4) + 1;
|
||||
else
|
||||
year_reg(7 downto 4) <= "0000";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
elsif days_reg(3 downto 0) /= "1001" then
|
||||
days_reg(3 downto 0) <= days_reg(3 downto 0) + 1;
|
||||
else
|
||||
days_reg(3 downto 0) <= (others => '0');
|
||||
days_reg(5 downto 4) <= days_reg(5 downto 4) + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
-- DM binary data mode
|
||||
-- else
|
||||
-- if seconds_reg /= x"3B" then
|
||||
-- seconds_reg <= seconds_reg + 1;
|
||||
-- else
|
||||
-- seconds_reg <= (others => '0');
|
||||
-- if minutes_reg /= x"3B" then
|
||||
-- minutes_reg <= minutes_reg + 1;
|
||||
-- else
|
||||
-- minutes_reg <= (others => '0');
|
||||
-- if b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) = "001100" then
|
||||
-- hours_reg(7 downto 0) <= "10000001";
|
||||
-- elsif ((b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) /= "011100") and
|
||||
-- (b_reg(1) & hours_reg(4 downto 0) /= "110111")) then
|
||||
-- hours_reg(4 downto 0) <= hours_reg(4 downto 0) + 1;
|
||||
-- else
|
||||
-- if b_reg(1) = '0' then
|
||||
-- hours_reg(7 downto 0) <= "00000001";
|
||||
-- else
|
||||
-- hours_reg <= (others => '0');
|
||||
-- end if;
|
||||
-- if weeks_reg /= x"07" then
|
||||
-- weeks_reg <= weeks_reg + 1;
|
||||
-- else
|
||||
-- weeks_reg <= x"01"; -- Sunday = 1
|
||||
-- end if;
|
||||
-- if ((month_reg & days_reg & leap_reg = X"021C" & "01") or
|
||||
-- (month_reg & days_reg & leap_reg = X"021C" & "10") or
|
||||
-- (month_reg & days_reg & leap_reg = X"021C" & "11") or
|
||||
-- (month_reg & days_reg & leap_reg = X"021D" & "00") or
|
||||
-- (month_reg & days_reg = X"041E") or
|
||||
-- (month_reg & days_reg = X"061E") or
|
||||
-- (month_reg & days_reg = X"091E") or
|
||||
-- (month_reg & days_reg = X"0B1E") or
|
||||
-- ( days_reg = X"1F")) then
|
||||
-- days_reg <= x"01";
|
||||
-- if month_reg /= x"0C" then
|
||||
-- month_reg <= month_reg + 1;
|
||||
-- else
|
||||
-- month_reg <= x"01";
|
||||
-- leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1;
|
||||
-- if year_reg /= x"63" then
|
||||
-- year_reg <= year_reg + 1;
|
||||
-- else
|
||||
-- year_reg <= x"00";
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- else
|
||||
-- days_reg <= days_reg + 1;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- 50 Bytes of General Purpose RAM
|
||||
SE11: entity work.CMOS
|
||||
port map (
|
||||
clock => CLK,
|
||||
data => DI,
|
||||
rdaddress => A,
|
||||
wraddress => A,
|
||||
wren => WR and CS,
|
||||
q => CMOS_Dout
|
||||
);
|
||||
|
||||
end rtl;
|
22
src/tsconf.v
22
src/tsconf.v
@ -787,17 +787,17 @@ end
|
||||
|
||||
mc146818a SE9
|
||||
(
|
||||
.reset(reset),
|
||||
.clk(clk_28mhz),
|
||||
.ena(ena_0_4375mhz),
|
||||
.cs(1),
|
||||
.keyscancode(key_scancode),
|
||||
.rtc(RTC),
|
||||
.cmoscfg(CMOSCfg),
|
||||
.wr(mc146818a_wr),
|
||||
.a(gluclock_addr[7:0]),
|
||||
.di(cpu_do_bus),
|
||||
.do(mc146818a_do_bus)
|
||||
.RESET(reset),
|
||||
.CLK(clk_28mhz),
|
||||
.ENA(ena_0_4375mhz),
|
||||
.CS(1),
|
||||
.KEYSCANCODE(key_scancode),
|
||||
.RTC(RTC),
|
||||
.CMOSCfg(CMOSCfg),
|
||||
.WR(mc146818a_wr),
|
||||
.A(gluclock_addr[7:0]),
|
||||
.DI(cpu_do_bus),
|
||||
.DO(mc146818a_do_bus)
|
||||
);
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user