mirror of
https://github.com/MikhaelKaa/zx_cartridge.git
synced 2026-03-16 14:37:57 +03:00
init
This commit is contained in:
parent
ef64772818
commit
2f6216192d
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/FW/src/*.bak
|
||||
/FW/src/*.vcd
|
||||
/HW/src/__Previews/*.SchDocPreview
|
||||
/FW/output_files
|
||||
/FW/incremental_db
|
||||
/FW/db
|
||||
/HW/History
|
||||
/FW/*.qws
|
||||
/HW/Project Logs for fix/*.LOG
|
||||
/HW/Project Logs for zx_cartridge/*.LOG
|
||||
/FW/zx_cartrige_description.txt
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "HW/altium_libs"]
|
||||
path = HW/altium_libs
|
||||
url = https://github.com/MikhaelKaa/altium_libs.git
|
||||
14
FW/src/makefile
Normal file
14
FW/src/makefile
Normal file
@ -0,0 +1,14 @@
|
||||
# Для тестирования модуля неодходимо чтобы тест назывался %имя_модуля%_tb
|
||||
|
||||
TARGET ?= zx_cartrige
|
||||
ICARUS = iverilog
|
||||
|
||||
all:
|
||||
rm -f $(TARGET)
|
||||
$(ICARUS) -g2012 -o $(TARGET) $(TARGET).v $(TARGET)_tb.v
|
||||
vvp $(TARGET)
|
||||
rm -f $(TARGET)
|
||||
clean:
|
||||
rm -f $(TARGET) $(TARGET).vcd
|
||||
|
||||
.PHONY: all clean
|
||||
55
FW/src/zx_cartrige.v
Normal file
55
FW/src/zx_cartrige.v
Normal file
@ -0,0 +1,55 @@
|
||||
`timescale 1ns / 1ps
|
||||
// ZX SPECTRUM cartrige module
|
||||
// 17.02.2026 Mikhael Kaa
|
||||
// CPU adr bus A0...A12 connect directly to CR_ROM chip
|
||||
module zx_cartrige #(
|
||||
// default example parameter
|
||||
parameter SELF_LOCK_VAL = 10
|
||||
)(
|
||||
// Reset
|
||||
input reset_n,
|
||||
// CPU ctrl signals
|
||||
input iorq_n,
|
||||
input rd_n,
|
||||
input mreq_n,
|
||||
// Part of CPU adr bus
|
||||
input A7,
|
||||
input A13,
|
||||
input A14,
|
||||
input A15,
|
||||
|
||||
// ZX ROM block
|
||||
output ZX_ROM_blk,
|
||||
// Cartrige ROM enable
|
||||
output CR_ROM_oe_n,
|
||||
// Up part cartrige ROM adr bus (A13...A18)
|
||||
output [5:0] CR_ROM_A
|
||||
);
|
||||
// CR_ROM 8kb bank counter
|
||||
reg [5:0] CR_ROM_bank_cnt = 6'b0;
|
||||
// Self lock register, disable all logic and CR_ROM
|
||||
reg self_lock = 1'b0;
|
||||
// rd or wr port 0x7f increment CR_ROM bank
|
||||
wire rom_page_up = iorq_n | A7 | self_lock;
|
||||
// CPU work with 0000...1fff adr
|
||||
wire lower_rom = ({A13, A14, A15} == 3'b000) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(negedge rom_page_up or negedge reset_n) begin
|
||||
if(!reset_n) begin
|
||||
CR_ROM_bank_cnt <= 6'b0;
|
||||
self_lock <= 1'b0;
|
||||
end else begin
|
||||
// increment bank counter
|
||||
CR_ROM_bank_cnt <= CR_ROM_bank_cnt + 1'b1;
|
||||
// check self lock
|
||||
if(CR_ROM_bank_cnt == SELF_LOCK_VAL) begin
|
||||
self_lock <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign CR_ROM_oe_n = ~lower_rom | rd_n | mreq_n | self_lock ;
|
||||
assign ZX_ROM_blk = ~CR_ROM_oe_n;
|
||||
assign CR_ROM_A = CR_ROM_bank_cnt;
|
||||
|
||||
endmodule
|
||||
142
FW/src/zx_cartrige_tb.v
Normal file
142
FW/src/zx_cartrige_tb.v
Normal file
@ -0,0 +1,142 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module tb_zx_cartrige();
|
||||
reg reset_n;
|
||||
reg iorq_n;
|
||||
reg rd_n;
|
||||
reg mreq_n;
|
||||
reg A7, A13, A14, A15;
|
||||
|
||||
wire ZX_ROM_blk;
|
||||
wire CR_ROM_oe_n;
|
||||
wire [5:0] CR_ROM_A;
|
||||
|
||||
// DUT с уменьшенным параметром для быстрой проверки
|
||||
zx_cartrige #(
|
||||
.SELF_LOCK_VAL(3)
|
||||
) uut (
|
||||
.reset_n(reset_n),
|
||||
.iorq_n(iorq_n),
|
||||
.rd_n(rd_n),
|
||||
.mreq_n(mreq_n),
|
||||
.A7(A7),
|
||||
.A13(A13),
|
||||
.A14(A14),
|
||||
.A15(A15),
|
||||
.ZX_ROM_blk(ZX_ROM_blk),
|
||||
.CR_ROM_oe_n(CR_ROM_oe_n),
|
||||
.CR_ROM_A(CR_ROM_A)
|
||||
);
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_zx_cartrige.vcd");
|
||||
$dumpvars(0, tb_zx_cartrige);
|
||||
|
||||
// Исходное состояние: сброс активен
|
||||
reset_n = 0;
|
||||
iorq_n = 1;
|
||||
rd_n = 1;
|
||||
mreq_n = 1;
|
||||
A7 = 0;
|
||||
A13 = 0;
|
||||
A14 = 0;
|
||||
A15 = 0;
|
||||
#100;
|
||||
reset_n = 1;
|
||||
#10;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Test 1: Инкремент происходит только при A7=0 и спаде iorq_n
|
||||
// ------------------------------------------------------------
|
||||
$display("=== Test 1: Increment condition (A7=0 and iorq_n falling) ===");
|
||||
|
||||
if (CR_ROM_A !== 0) $display("ERROR: Initial CR_ROM_A = %d, expected 0", CR_ROM_A);
|
||||
|
||||
// Попытка инкремента с A7=1 – не должен инкрементироваться
|
||||
A7 = 1;
|
||||
iorq_n = 0; // rom_page_up = 0|1|0 = 1 – нет изменения
|
||||
#10;
|
||||
iorq_n = 1;
|
||||
#10;
|
||||
if (CR_ROM_A !== 0) $display("ERROR: Increment occurred while A7=1, CR_ROM_A = %d", CR_ROM_A);
|
||||
|
||||
// Теперь A7=0, создаём отрицательный фронт iorq_n
|
||||
A7 = 0;
|
||||
iorq_n = 1;
|
||||
#10;
|
||||
iorq_n = 0; // rom_page_up: 1->0 -> negedge
|
||||
#10;
|
||||
if (CR_ROM_A !== 1) $display("ERROR: No increment when A7=0 and iorq_n falling, CR_ROM_A = %d", CR_ROM_A);
|
||||
|
||||
iorq_n = 1;
|
||||
#10;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Test 2: Достижение SELF_LOCK_VAL блокирует активацию CR_ROM_oe_n
|
||||
// ------------------------------------------------------------
|
||||
$display("=== Test 2: Self-lock prevents CR_ROM_oe_n activation ===");
|
||||
|
||||
// Инкрементируем до 2
|
||||
iorq_n = 0; #10; iorq_n = 1; #10; // CR_ROM_A=2
|
||||
iorq_n = 0; #10; iorq_n = 1; #10; // CR_ROM_A=3 (lock)
|
||||
if (CR_ROM_A !== 3) $display("ERROR: Failed to reach lock, CR_ROM_A = %d", CR_ROM_A);
|
||||
|
||||
// self_lock активен. Проверим, что CR_ROM_oe_n всегда 1 при попытке активации
|
||||
// Необходимые условия: lower_rom=1 (A13=A14=A15=0), rd_n=0, mreq_n=0
|
||||
A13 = 0; A14 = 0; A15 = 0;
|
||||
rd_n = 0;
|
||||
mreq_n = 0;
|
||||
#10;
|
||||
if (CR_ROM_oe_n !== 0) $display("ERROR: CR_ROM_oe_n = %b, expected 1 (self_lock active)", CR_ROM_oe_n);
|
||||
if (ZX_ROM_blk !== 1) $display("ERROR: ZX_ROM_blk = %b, expected 0", ZX_ROM_blk);
|
||||
|
||||
rd_n = 1; mreq_n = 1;
|
||||
#10;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Test 3: CR_ROM_oe_n активируется при обращении в нижние 8кб
|
||||
// Условия: lower_rom=1, rd_n=0, mreq_n=0, self_lock=0
|
||||
// ------------------------------------------------------------
|
||||
$display("=== Test 3: CR_ROM_oe_n activation in lower ROM area ===");
|
||||
|
||||
// Сброс для снятия self_lock
|
||||
reset_n = 0;
|
||||
#10;
|
||||
reset_n = 1;
|
||||
#10;
|
||||
if (CR_ROM_A !== 0) $display("ERROR: After reset CR_ROM_A = %d, expected 0", CR_ROM_A);
|
||||
|
||||
// Устанавливаем условия для активации
|
||||
A13 = 0; A14 = 0; A15 = 0; // lower_rom = 1
|
||||
rd_n = 0;
|
||||
mreq_n = 0;
|
||||
#10;
|
||||
|
||||
// Ожидаем CR_ROM_oe_n = 0 (активен)
|
||||
if (CR_ROM_oe_n !== 0) $display("ERROR: CR_ROM_oe_n = %b, expected 0 during lower ROM access (rd_n=0, mreq_n=0)", CR_ROM_oe_n);
|
||||
if (ZX_ROM_blk !== 1) $display("ERROR: ZX_ROM_blk = %b, expected 1", ZX_ROM_blk);
|
||||
|
||||
// Проверка, что при выходе из нижней области (lower_rom=0) выход отключается
|
||||
A13 = 1; // теперь lower_rom = 0 (A13=1, остальные 0)
|
||||
#10;
|
||||
if (CR_ROM_oe_n !== 1) $display("ERROR: CR_ROM_oe_n = %b, expected 1 when not in lower ROM", CR_ROM_oe_n);
|
||||
|
||||
// Проверка, что при rd_n=1 выход отключается
|
||||
A13 = 0; // обратно в lower_rom=1
|
||||
rd_n = 1;
|
||||
#10;
|
||||
if (CR_ROM_oe_n !== 1) $display("ERROR: CR_ROM_oe_n = %b, expected 1 when rd_n=1", CR_ROM_oe_n);
|
||||
|
||||
// Проверка, что при mreq_n=1 выход отключается
|
||||
rd_n = 0; mreq_n = 1;
|
||||
#10;
|
||||
if (CR_ROM_oe_n !== 1) $display("ERROR: CR_ROM_oe_n = %b, expected 1 when mreq_n=1", CR_ROM_oe_n);
|
||||
|
||||
rd_n = 1; mreq_n = 1;
|
||||
#10;
|
||||
|
||||
$display("=== All tests completed ===");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
31
FW/zx_cartrige.qpf
Normal file
31
FW/zx_cartrige.qpf
Normal file
@ -0,0 +1,31 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 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.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
|
||||
# Date created = 17:08:17 February 17, 2026
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "13.0"
|
||||
DATE = "17:08:17 February 17, 2026"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "zx_cartrige"
|
||||
PROJECT_REVISION = "d_fix"
|
||||
70
FW/zx_cartrige.qsf
Normal file
70
FW/zx_cartrige.qsf
Normal file
@ -0,0 +1,70 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 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.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
|
||||
# Date created = 14:32:59 February 06, 2026
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# d_fix_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY MAX7000S
|
||||
set_global_assignment -name DEVICE "EPM7064SLC44-10"
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY zx_cartrige
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "14:32:59 FEBRUARY 06, 2026"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE PLCC
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 44
|
||||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 10
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD TTL
|
||||
set_location_assignment PIN_1 -to reset_n
|
||||
set_global_assignment -name VERILOG_FILE src/zx_cartrige.v
|
||||
set_global_assignment -name CDF_FILE output_files/Chain1.cdf
|
||||
set_location_assignment PIN_18 -to A7
|
||||
set_location_assignment PIN_19 -to A13
|
||||
set_location_assignment PIN_20 -to A14
|
||||
set_location_assignment PIN_21 -to A15
|
||||
set_location_assignment PIN_31 -to CR_ROM_A[5]
|
||||
set_location_assignment PIN_29 -to CR_ROM_A[4]
|
||||
set_location_assignment PIN_28 -to CR_ROM_A[3]
|
||||
set_location_assignment PIN_9 -to CR_ROM_A[2]
|
||||
set_location_assignment PIN_11 -to CR_ROM_A[1]
|
||||
set_location_assignment PIN_12 -to CR_ROM_A[0]
|
||||
set_location_assignment PIN_34 -to CR_ROM_oe_n
|
||||
set_location_assignment PIN_27 -to ZX_ROM_blk
|
||||
set_location_assignment PIN_24 -to iorq_n
|
||||
set_location_assignment PIN_25 -to mreq_n
|
||||
set_location_assignment PIN_26 -to rd_n
|
||||
1
HW/altium_libs
Submodule
1
HW/altium_libs
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c41200a6ad7d258b53d009f64863589a1fd4ec8b
|
||||
BIN
HW/src/main.SchDoc
Normal file
BIN
HW/src/main.SchDoc
Normal file
Binary file not shown.
BIN
HW/src/pcb.PcbDoc
Normal file
BIN
HW/src/pcb.PcbDoc
Normal file
Binary file not shown.
1811
HW/zx_cartridge.PrjPCB
Normal file
1811
HW/zx_cartridge.PrjPCB
Normal file
File diff suppressed because it is too large
Load Diff
1
HW/zx_cartridge.PrjPCBStructure
Normal file
1
HW/zx_cartridge.PrjPCBStructure
Normal file
@ -0,0 +1 @@
|
||||
Record=TopLevelDocument|FileName=main.SchDoc
|
||||
Loading…
Reference in New Issue
Block a user