1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-25 19:45:57 +00:00

Delete Pet2001 Files

This commit is contained in:
Marcel
2022-07-23 14:29:51 +02:00
parent 84a955e7f6
commit e61740cda2
27 changed files with 0 additions and 37267 deletions

View File

@@ -1,30 +0,0 @@
# -------------------------------------------------------------------------- #
#
# 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.1.0 Build 162 10/23/2013 SJ Web Edition
# Date created = 10:56:12 January 03, 2017
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.1"
DATE = "10:56:12 January 03, 2017"
# Revisions
PROJECT_REVISION = "Pet2001"

View File

@@ -1,33 +0,0 @@
#************************************************************
# THIS IS A WIZARD-GENERATED FILE.
#
# Version 13.1.4 Build 182 03/12/2014 SJ Full Version
#
#************************************************************
# Copyright (C) 1991-2014 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.
# Clock constraints
create_clock -name "CLOCK_27" -period 37.037 [get_ports {CLOCK_27}]
create_clock -name {SPI_SCK} -period 10.000 -waveform { 0.000 0.500 } [get_ports {SPI_SCK}]
# Automatically constrain PLL and other generated clocks
derive_pll_clocks -create_base_clocks
# Automatically calculate clock uncertainty to jitter and other effects.
derive_clock_uncertainty

View File

@@ -1,15 +0,0 @@
@echo off
del /s *.bak
del /s *.orig
del /s *.rej
rmdir /s /q db
rmdir /s /q incremental_db
rmdir /s /q output_files
rmdir /s /q simulation
rmdir /s /q greybox_tmp
del PLLJ_PLLSPE_INFO.txt
del *.qws
del *.ppf
del *.qip
del *.ddb
pause

View File

@@ -1,301 +0,0 @@
`timescale 1ns / 1ps
//Pet2001 Mist Toplevel 2017 Gehstock
module Pet2001
(
output LED,
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
output VGA_HS,
output VGA_VS,
output AUDIO_L,
output AUDIO_R,
input SPI_SCK,
output SPI_DO,
input SPI_DI,
input SPI_SS2,
input SPI_SS3,
input CONF_DATA0,
input CLOCK_27,
output [12:0] SDRAM_A,
inout [15:0] SDRAM_DQ,
output SDRAM_DQML,
output SDRAM_DQMH,
output SDRAM_nWE,
output SDRAM_nCAS,
output SDRAM_nRAS,
output SDRAM_nCS,
output [1:0] SDRAM_BA,
output SDRAM_CLK,
output SDRAM_CKE
);
//////////////////////////////////////////////////////////////////////
// MiST I/O //
//////////////////////////////////////////////////////////////////////
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
wire scandoubler_disable;
wire ypbpr;
wire ps2_kbd_clk, ps2_kbd_data;
`include "rtl\build_id.v"
localparam CONF_STR =
{
"PET2001;TAPPRG;",
"O78,TAP mode,Fast,Normal,Normal+Sound;",
"O9A,CPU Speed,Normal,x2,x4,x8;",
"O2,Screen Color,White,Green;",
"O3,Diag,Off,On(needs Reset);",
"O56,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
"T7,Reset;",
"V,v0.61.",`BUILD_DATE
};
wire ioctl_download;
wire [7:0] ioctl_index;
wire ioctl_wr;
wire [24:0] ioctl_addr;
wire [7:0] ioctl_dout;
mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
(
.clk_sys (clk ),
.conf_str (CONF_STR ),
.SPI_SCK (SPI_SCK ),
.CONF_DATA0 (CONF_DATA0 ),
.SPI_SS2 (SPI_SS2 ),
.SPI_DO (SPI_DO ),
.SPI_DI (SPI_DI ),
.buttons (buttons ),
.switches (switches ),
.scandoubler_disable(scandoubler_disable),
.ypbpr (ypbpr ),
.ps2_kbd_clk (ps2_kbd_clk ),
.ps2_kbd_data (ps2_kbd_data ),
.ps2_caps_led (shift_lock ),
.status (status ),
.ioctl_download (ioctl_download ),
.ioctl_index (ioctl_index ),
.ioctl_wr (ioctl_wr ),
.ioctl_addr (ioctl_addr ),
.ioctl_dout (ioctl_dout )
);
//////////////////////////////////////////////////////////////////////
// Global Clock and System Reset. //
//////////////////////////////////////////////////////////////////////
wire clk, sdram_clk;
wire locked;
pll pll
(
.inclk0(CLOCK_27),
.c0(sdram_clk), //112Mhz
.c1(SDRAM_CLK), //112Mhz
.c2(clk), //56MHz
.locked(locked)
);
reg reset = 1;
wire RESET = status[0] | buttons[1] | status[7];
always @(posedge clk) begin
integer initRESET = 20000000;
reg [3:0] reset_cnt;
if ((!RESET && reset_cnt==4'd14) && !initRESET)
reset <= 0;
else begin
if(initRESET) initRESET <= initRESET - 1;
reset <= 1;
reset_cnt <= reset_cnt+4'd1;
end
end
////////////////////////////////////////////////////////////////////
// Clocks
////////////////////////////////////////////////////////////////////
reg ce_7mp;
reg ce_7mn;
reg ce_1m;
wire [6:0] cpu_rates[4] = '{55, 27, 13, 6};
always @(negedge clk) begin
reg [4:0] div = 0;
reg [6:0] cpu_div = 0;
reg [6:0] cpu_rate = 55;
div <= div + 1'd1;
ce_7mp <= !div[2] & !div[1:0];
ce_7mn <= div[2] & !div[1:0];
cpu_div <= cpu_div + 1'd1;
if(cpu_div == cpu_rate) begin
cpu_div <= 0;
cpu_rate <= (tape_active && !status[8:7]) ? 7'd2 : cpu_rates[status[10:9]];
end
ce_1m <= ~(tape_active & ~ram_ready) && !cpu_div;
end
///////////////////////////////////////////////////
// RAM
///////////////////////////////////////////////////
wire ram_ready;
sram ram
(
.*,
.clk(sdram_clk),
.init(~locked),
.dout(tape_data),
.din (ioctl_dout),
.addr(ioctl_download ? ioctl_addr : tape_addr),
.wtbt(0),
.we( ioctl_download && ioctl_wr && (ioctl_index == 1)),
.rd(!ioctl_download && tape_rd),
.ready(ram_ready)
);
///////////////////////////////////////////////////
// CPU
///////////////////////////////////////////////////
wire [15:0] addr;
wire [7:0] cpu_data_out;
wire [7:0] cpu_data_in;
wire we;
wire irq;
cpu6502 cpu
(
.clk(clk),
.ce(ce_1m),
.reset(reset),
.nmi(0),
.irq(irq),
.din(cpu_data_in),
.dout(cpu_data_out),
.addr(addr),
.we(we)
);
///////////////////////////////////////////////////
// Commodore Pet hardware
///////////////////////////////////////////////////
wire pix;
wire HSync, VSync;
wire audioDat;
pet2001hw hw
(
.*,
.data_out(cpu_data_in),
.data_in(cpu_data_out),
.cass_motor_n(),
.cass_write(tape_write),
.audio(audioDat),
.cass_sense_n(0),
.cass_read(tape_audio),
.diag_l(!status[3]),
.dma_addr(dma_off[13:0]+ioctl_addr[13:0]-2'd2),
.dma_din(ioctl_dout),
.dma_dout(),
.dma_we(ioctl_wr && ioctl_download && (ioctl_index == 8'h41) && (ioctl_addr>1)),
.clk_speed(0),
.clk_stop(0)
);
reg [15:0] dma_off;
always @(posedge clk) begin
if(ioctl_wr && ioctl_download && (ioctl_index == 8'h41)) begin
if(ioctl_addr == 0) dma_off[7:0] <= ioctl_dout;
if(ioctl_addr == 1) dma_off[15:8] <= ioctl_dout;
end
end
////////////////////////////////////////////////////////////////////
// Video //
////////////////////////////////////////////////////////////////////
wire [2:0] G = {3{pix}};
wire [2:0] R = status[2] ? 3'd0 : G;
wire [2:0] B = R;
video_mixer #(.LINE_LENGTH(448), .HALF_DEPTH(1)) video_mixer
(
.*,
.clk_sys(clk),
.ce_pix(ce_7mp),
.ce_pix_actual(ce_7mp),
.scanlines(scandoubler_disable ? 2'b00 : {status[6:5] == 3, status[6:5] == 2}),
.hq2x(status[6:5]==1),
.ypbpr_full(1),
.line_start(0),
.mono(0)
);
////////////////////////////////////////////////////////////////////
// Audio //
////////////////////////////////////////////////////////////////////
assign AUDIO_R = AUDIO_L;
sigma_delta_dac #(.MSBI(1)) dac
(
.CLK(clk),
.RESET(reset),
.DACin({audioDat ^ tape_write, tape_audio & tape_active & (status[8:7] == 2)}),
.DACout(AUDIO_L)
);
assign LED = ~(tape_led | ioctl_download);
wire tape_audio;
wire tape_rd;
wire [24:0] tape_addr;
wire [7:0] tape_data;
wire tape_pause = 0;
wire tape_active;
wire tape_write;
tape tape(.*, .ioctl_download(ioctl_download && (ioctl_index==1)));
reg [18:0] act_cnt;
wire tape_led = act_cnt[18] ? act_cnt[17:10] <= act_cnt[7:0] : act_cnt[17:10] > act_cnt[7:0];
always @(posedge clk) if((|status[8:7] ? ce_1m : ce_7mp) && (tape_active || act_cnt[18] || act_cnt[17:0])) act_cnt <= act_cnt + 1'd1;
//////////////////////////////////////////////////////////////////////
// PS/2 to PET keyboard interface
//////////////////////////////////////////////////////////////////////
wire [7:0] keyin;
wire [3:0] keyrow;
wire shift_lock;
keyboard keyboard(.*, .Fn(), .mod());
endmodule // pet2001

View File

@@ -1,35 +0,0 @@
# ================================================================================
#
# Build ID Verilog Module Script
# Jeff Wiencrot - 8/1/2011
#
# Generates a Verilog module that contains a timestamp,
# from the current build. These values are available from the build_date, build_time,
# physical_address, and host_name output ports of the build_id module in the build_id.v
# Verilog source file.
#
# ================================================================================
proc generateBuildID_Verilog {} {
# Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
set buildDate [ clock format [ clock seconds ] -format %y%m%d ]
set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
# Create a Verilog file for output
set outputFileName "rtl/build_id.v"
set outputFile [open $outputFileName "w"]
# Output the Verilog source
puts $outputFile "`define BUILD_DATE \"$buildDate\""
puts $outputFile "`define BUILD_TIME \"$buildTime\""
close $outputFile
# Send confirmation message to the Messages window
post_message "Generated build identification Verilog module: [pwd]/$outputFileName"
post_message "Date: $buildDate"
post_message "Time: $buildTime"
}
# Comment out this line to prevent the process from automatically executing when the file is sourced:
generateBuildID_Verilog

View File

@@ -1,87 +0,0 @@
-- -----------------------------------------------------------------------
--
-- FPGA 64
--
-- A fully functional commodore 64 implementation in a single FPGA
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/fpga64.html
-- -----------------------------------------------------------------------
--
-- Interface to 6502/6510 core
--
-- -----------------------------------------------------------------------
library IEEE;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
-- -----------------------------------------------------------------------
entity cpu65xx is
generic (
pipelineOpcode : boolean;
pipelineAluMux : boolean;
pipelineAluOut : boolean
);
port (
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
nmi_n : in std_logic;
irq_n : in std_logic;
so_n : in std_logic := '1';
di : in unsigned(7 downto 0);
do : out unsigned(7 downto 0);
addr : out unsigned(15 downto 0);
we : out std_logic;
debugOpcode : out unsigned(7 downto 0);
debugPc : out unsigned(15 downto 0);
debugA : out unsigned(7 downto 0);
debugX : out unsigned(7 downto 0);
debugY : out unsigned(7 downto 0);
debugS : out unsigned(7 downto 0)
);
end cpu65xx;
library IEEE;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
entity cpu6502 is
port(
clk : in std_logic;
ce : in std_logic;
reset : in std_logic;
nmi : in std_logic;
irq : in std_logic;
din : in unsigned(7 downto 0);
dout : out unsigned(7 downto 0);
addr : out unsigned(15 downto 0);
we : out std_logic
);
end cpu6502;
architecture cpu6502 of cpu6502 is
begin
cpuInstance: entity work.cpu65xx(fast)
generic map (
pipelineOpcode => false,
pipelineAluMux => false,
pipelineAluOut => false
)
port map (
clk => clk,
enable=> ce,
reset => reset,
nmi_n => not nmi,
irq_n => not irq,
di => din,
do => dout,
addr => addr,
we => we
);
end architecture;

File diff suppressed because it is too large Load Diff

View File

@@ -1,454 +0,0 @@
//
//
// Copyright (c) 2012-2013 Ludvig Strigeus
// Copyright (c) 2017 Sorgelig
//
// This program is GPL Licensed. See COPYING for the full license.
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
`define BITS_TO_FIT(N) ( \
N <= 2 ? 0 : \
N <= 4 ? 1 : \
N <= 8 ? 2 : \
N <= 16 ? 3 : \
N <= 32 ? 4 : \
N <= 64 ? 5 : \
N <= 128 ? 6 : \
N <= 256 ? 7 : \
N <= 512 ? 8 : \
N <=1024 ? 9 : 10 )
module hq2x_in #(parameter LENGTH, parameter DWIDTH)
(
input clk,
input [AWIDTH:0] rdaddr,
input rdbuf,
output[DWIDTH:0] q,
input [AWIDTH:0] wraddr,
input wrbuf,
input [DWIDTH:0] data,
input wren
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
wire [DWIDTH:0] out[2];
assign q = out[rdbuf];
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
endmodule
module hq2x_out #(parameter LENGTH, parameter DWIDTH)
(
input clk,
input [AWIDTH:0] rdaddr,
input [1:0] rdbuf,
output[DWIDTH:0] q,
input [AWIDTH:0] wraddr,
input [1:0] wrbuf,
input [DWIDTH:0] data,
input wren
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH*2);
wire [DWIDTH:0] out[4];
assign q = out[rdbuf];
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]);
endmodule
module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH)
(
input clock,
input [DWIDTH:0] data,
input [AWIDTH:0] rdaddress,
input [AWIDTH:0] wraddress,
input wren,
output [DWIDTH:0] q
);
altsyncram altsyncram_component (
.address_a (wraddress),
.clock0 (clock),
.data_a (data),
.wren_a (wren),
.address_b (rdaddress),
.q_b(q),
.aclr0 (1'b0),
.aclr1 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.data_b ({(DWIDTH+1){1'b1}}),
.eccstatus (),
.q_a (),
.rden_a (1'b1),
.rden_b (1'b1),
.wren_b (1'b0));
defparam
altsyncram_component.address_aclr_b = "NONE",
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = NUMWORDS,
altsyncram_component.numwords_b = NUMWORDS,
altsyncram_component.operation_mode = "DUAL_PORT",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
altsyncram_component.widthad_a = AWIDTH+1,
altsyncram_component.widthad_b = AWIDTH+1,
altsyncram_component.width_a = DWIDTH+1,
altsyncram_component.width_b = DWIDTH+1,
altsyncram_component.width_byteena_a = 1;
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////////
module DiffCheck
(
input [17:0] rgb1,
input [17:0] rgb2,
output result
);
wire [5:0] r = rgb1[5:1] - rgb2[5:1];
wire [5:0] g = rgb1[11:7] - rgb2[11:7];
wire [5:0] b = rgb1[17:13] - rgb2[17:13];
wire [6:0] t = $signed(r) + $signed(b);
wire [6:0] gx = {g[5], g};
wire [7:0] y = $signed(t) + $signed(gx);
wire [6:0] u = $signed(r) - $signed(b);
wire [7:0] v = $signed({g, 1'b0}) - $signed(t);
// if y is inside (-24..24)
wire y_inside = (y < 8'h18 || y >= 8'he8);
// if u is inside (-4, 4)
wire u_inside = (u < 7'h4 || u >= 7'h7c);
// if v is inside (-6, 6)
wire v_inside = (v < 8'h6 || v >= 8'hfA);
assign result = !(y_inside && u_inside && v_inside);
endmodule
module InnerBlend
(
input [8:0] Op,
input [5:0] A,
input [5:0] B,
input [5:0] C,
output [5:0] O
);
function [8:0] mul6x3;
input [5:0] op1;
input [2:0] op2;
begin
mul6x3 = 9'd0;
if(op2[0]) mul6x3 = mul6x3 + op1;
if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0};
if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00};
end
endfunction
wire OpOnes = Op[4];
wire [8:0] Amul = mul6x3(A, Op[7:5]);
wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0});
wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0});
wire [8:0] At = Amul;
wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B};
wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C};
wire [9:0] Res = {At, 1'b0} + Bt + Ct;
assign O = Op[8] ? A : Res[9:4];
endmodule
module Blend
(
input [5:0] rule,
input disable_hq2x,
input [17:0] E,
input [17:0] A,
input [17:0] B,
input [17:0] D,
input [17:0] F,
input [17:0] H,
output [17:0] Result
);
reg [1:0] input_ctrl;
reg [8:0] op;
localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A
localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4
localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4
localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4
localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4
localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4
localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4
localparam AB = 2'b00;
localparam AD = 2'b01;
localparam DB = 2'b10;
localparam BD = 2'b11;
wire is_diff;
DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff);
always @* begin
case({!is_diff, rule[5:2]})
1,17: {op, input_ctrl} = {BLEND1, AB};
2,18: {op, input_ctrl} = {BLEND1, DB};
3,19: {op, input_ctrl} = {BLEND1, BD};
4,20: {op, input_ctrl} = {BLEND2, DB};
5,21: {op, input_ctrl} = {BLEND2, AB};
6,22: {op, input_ctrl} = {BLEND2, AD};
8: {op, input_ctrl} = {BLEND0, 2'bxx};
9: {op, input_ctrl} = {BLEND0, 2'bxx};
10: {op, input_ctrl} = {BLEND0, 2'bxx};
11: {op, input_ctrl} = {BLEND1, AB};
12: {op, input_ctrl} = {BLEND1, AB};
13: {op, input_ctrl} = {BLEND1, AB};
14: {op, input_ctrl} = {BLEND1, DB};
15: {op, input_ctrl} = {BLEND1, BD};
24: {op, input_ctrl} = {BLEND2, DB};
25: {op, input_ctrl} = {BLEND5, DB};
26: {op, input_ctrl} = {BLEND6, DB};
27: {op, input_ctrl} = {BLEND2, DB};
28: {op, input_ctrl} = {BLEND4, DB};
29: {op, input_ctrl} = {BLEND5, DB};
30: {op, input_ctrl} = {BLEND3, BD};
31: {op, input_ctrl} = {BLEND3, DB};
default: {op, input_ctrl} = 11'bx;
endcase
// Setting op[8] effectively disables HQ2X because blend will always return E.
if (disable_hq2x) op[8] = 1;
end
// Generate inputs to the inner blender. Valid combinations.
// 00: E A B
// 01: E A D
// 10: E D B
// 11: E B D
wire [17:0] Input1 = E;
wire [17:0] Input2 = !input_ctrl[1] ? A :
!input_ctrl[0] ? D : B;
wire [17:0] Input3 = !input_ctrl[0] ? B : D;
InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]);
InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]);
InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]);
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////
module Hq2x #(parameter LENGTH, parameter HALF_DEPTH)
(
input clk,
input ce_x4,
input [DWIDTH:0] inputpixel,
input mono,
input disable_hq2x,
input reset_frame,
input reset_line,
input [1:0] read_y,
input [AWIDTH+1:0] read_x,
output [DWIDTH:0] outpixel
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
localparam DWIDTH = HALF_DEPTH ? 8 : 17;
wire [5:0] hqTable[256] = '{
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
};
reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2;
reg [17:0] A, B, D, F, G, H;
reg [7:0] pattern, nextpatt;
reg [1:0] i;
reg [7:0] y;
wire curbuf = y[0];
reg prevbuf = 0;
wire iobuf = !curbuf;
wire diff0, diff1;
DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0);
DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1);
wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]};
wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G;
wire [17:0] blend_result;
Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result);
reg Curr2_addr1;
reg [AWIDTH:0] Curr2_addr2;
wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp;
wire [DWIDTH:0] Curr2tmp;
reg [AWIDTH:0] wrin_addr2;
reg [DWIDTH:0] wrpix;
reg wrin_en;
function [17:0] h2rgb;
input [8:0] v;
begin
h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]};
end
endfunction
function [8:0] rgb2h;
input [17:0] v;
begin
rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]};
end
endfunction
hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in
(
.clk(clk),
.rdaddr(Curr2_addr2),
.rdbuf(Curr2_addr1),
.q(Curr2tmp),
.wraddr(wrin_addr2),
.wrbuf(iobuf),
.data(wrpix),
.wren(wrin_en)
);
reg [1:0] wrout_addr1;
reg [AWIDTH+1:0] wrout_addr2;
reg wrout_en;
reg [DWIDTH:0] wrdata;
hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out
(
.clk(clk),
.rdaddr(read_x),
.rdbuf(read_y),
.q(outpixel),
.wraddr(wrout_addr2),
.wrbuf(wrout_addr1),
.data(wrdata),
.wren(wrout_en)
);
always @(posedge clk) begin
reg [AWIDTH:0] offs;
reg old_reset_line;
reg old_reset_frame;
wrout_en <= 0;
wrin_en <= 0;
if(ce_x4) begin
pattern <= new_pattern;
if(~&offs) begin
if (i == 0) begin
Curr2_addr1 <= prevbuf;
Curr2_addr2 <= offs;
end
if (i == 1) begin
Prev2 <= Curr2;
Curr2_addr1 <= curbuf;
Curr2_addr2 <= offs;
end
if (i == 2) begin
Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel;
wrpix <= inputpixel;
wrin_addr2 <= offs;
wrin_en <= 1;
end
if (i == 3) begin
offs <= offs + 1'd1;
end
if(HALF_DEPTH) wrdata <= rgb2h(blend_result);
else wrdata <= blend_result;
wrout_addr1 <= {curbuf, i[1]};
wrout_addr2 <= {offs, i[1]^i[0]};
wrout_en <= 1;
end
if(i==3) begin
nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]};
{A, G} <= {Prev0, Next0};
{B, F, H, D} <= {Prev1, Curr2, Next1, Curr0};
{Prev0, Prev1} <= {Prev1, Prev2};
{Curr0, Curr1} <= {Curr1, Curr2};
{Next0, Next1} <= {Next1, Next2};
end else begin
nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]};
{B, F, H, D} <= {F, H, D, B};
end
i <= i + 1'b1;
if(old_reset_line && ~reset_line) begin
old_reset_frame <= reset_frame;
offs <= 0;
i <= 0;
y <= y + 1'd1;
prevbuf <= curbuf;
if(old_reset_frame & ~reset_frame) begin
y <= 0;
prevbuf <= 0;
end
end
old_reset_line <= reset_line;
end
end
endmodule // Hq2x

View File

@@ -1,286 +0,0 @@
module keyboard
(
input reset,
input clk,
input ps2_kbd_clk,
input ps2_kbd_data,
input [3:0] keyrow,
output [7:0] keyin,
output reg shift_lock,
output reg [11:1] Fn = 0,
output reg [2:0] mod = 0
);
reg [3:0] prev_clk = 0;
reg [11:0] shift_reg = 12'hFFF;
wire[11:0] kdata = {ps2_kbd_data,shift_reg[11:1]};
wire [7:0] kcode = kdata[9:2];
reg [7:0] keys[10];
reg release_btn = 0;
reg [7:0] code;
assign keyin = keys[keyrow];
reg input_strobe = 0;
wire shift = mod[0];
always @(negedge clk) begin
reg old_reset = 0;
old_reset <= reset;
if(~old_reset & reset)begin
keys[0] <= 8'hFF;
keys[1] <= 8'hFF;
keys[2] <= 8'hFF;
keys[3] <= 8'hFF;
keys[4] <= 8'hFF;
keys[5] <= 8'hFF;
keys[6] <= 8'hFF;
keys[7] <= 8'hFF;
keys[8] <= 8'hFF;
keys[9] <= 8'hFF;
shift_lock <= 0;
end
if(input_strobe) begin
case(code)
8'h59: mod[0]<= ~release_btn; // right shift
8'h12: mod[0]<= ~release_btn; // Left shift
8'h11: mod[1]<= ~release_btn; // alt
8'h14: mod[2]<= ~release_btn; // ctrl
8'h05: Fn[1] <= ~release_btn; // F1
8'h06: Fn[2] <= ~release_btn; // F2
8'h04: Fn[3] <= ~release_btn; // F3
8'h0C: Fn[4] <= ~release_btn; // F4
8'h03: Fn[5] <= ~release_btn; // F5
8'h0B: Fn[6] <= ~release_btn; // F6
8'h83: Fn[7] <= ~release_btn; // F7
8'h0A: Fn[8] <= ~release_btn; // F8
8'h01: Fn[9] <= ~release_btn; // F9
8'h09: Fn[10]<= ~release_btn; // F10
8'h78: Fn[11]<= ~release_btn; // F11
endcase
case(code)
'h76: begin
keys[9][4] <= release_btn; // ESC -> STOP
if(~release_btn) keys[8][5] <= 1;
else keys[8][5] <= ~shift_lock;
end
'h05: begin
keys[9][4] <= release_btn; // F1 -> RUN
if(~release_btn) keys[8][5] <= 0;
else keys[8][5] <= ~shift_lock;
end
'h06: begin
keys[0][6] <= release_btn; // F2 -> CLR
if(~release_btn) keys[8][5] <= 0;
else keys[8][5] <= ~shift_lock;
end
'h71: begin
keys[1][7] <= release_btn; // DEL
if(~release_btn) keys[8][5] <= 1;
else keys[8][5] <= ~shift_lock;
end
'h70: begin
keys[1][7] <= release_btn; // INSERT
if(~release_btn) keys[8][5] <= 0;
else keys[8][5] <= ~shift_lock;
end
'h6C: begin
keys[0][6] <= release_btn; // HOME
if(~release_btn) keys[8][5] <= 1;
else keys[8][5] <= ~shift_lock;
end
'h72: begin
keys[1][6] <= release_btn; // DOWN
if(~release_btn) keys[8][5] <= 1;
else keys[8][5] <= ~shift_lock;
end
'h75: begin
keys[1][6] <= release_btn; // UP
if(~release_btn) keys[8][5] <= 0;
else keys[8][5] <= ~shift_lock;
end
'h74: begin
keys[0][7] <= release_btn; // RIGHT
if(~release_btn) keys[8][5] <= 1;
else keys[8][5] <= ~shift_lock;
end
'h6B: begin
keys[0][7] <= release_btn; // LEFT
if(~release_btn) keys[8][5] <= 0;
else keys[8][5] <= ~shift_lock;
end
'h58: begin
keys[8][5] <= release_btn ^ shift_lock; // CAPS -> R SHIFT
if(~release_btn) shift_lock <= ~shift_lock;
end
'h11: keys[8][5] <= release_btn ^ shift_lock; // ALT -> R SHIFT
'h14: keys[8][0] <= release_btn; // CTRL -> L SHIFT
'h1F: keys[9][0] <= release_btn; // L GUI -> REV ON/OFF
'h5A: keys[6][5] <= release_btn; // RETURN
'h66: keys[1][7] <= release_btn; // BKSP -> DEL
'h1C: keys[4][0] <= release_btn; // a
'h32: keys[6][2] <= release_btn; // b
'h21: keys[6][1] <= release_btn; // c
'h23: keys[4][1] <= release_btn; // d
'h24: keys[2][1] <= release_btn; // e
'h2B: keys[5][1] <= release_btn; // f
'h34: keys[4][2] <= release_btn; // g
'h33: keys[5][2] <= release_btn; // h
'h43: keys[3][3] <= release_btn; // i
'h3B: keys[4][3] <= release_btn; // j
'h42: keys[5][3] <= release_btn; // k
'h4B: keys[4][4] <= release_btn; // l
'h3A: keys[6][3] <= release_btn; // m
'h31: keys[7][2] <= release_btn; // n
'h44: keys[2][4] <= release_btn; // o
'h4D: keys[3][4] <= release_btn; // p
'h15: keys[2][0] <= release_btn; // q
'h2D: keys[3][1] <= release_btn; // r
'h1B: keys[5][0] <= release_btn; // s
'h2C: keys[2][2] <= release_btn; // t
'h3C: keys[2][3] <= release_btn; // u
'h2A: keys[7][1] <= release_btn; // v
'h1D: keys[3][0] <= release_btn; // w
'h22: keys[7][0] <= release_btn; // x
'h35: keys[3][2] <= release_btn; // y
'h1A: keys[6][0] <= release_btn; // z
'h54: keys[9][1] <= release_btn; // [
'h5B: keys[8][2] <= release_btn; // ]
'h5D: keys[1][3] <= release_btn; // \
'h29: keys[9][2] <= release_btn; // SPACE
'h16: begin
keys[6][6] <= release_btn | shift; // 1
keys[0][0] <= release_btn | ~shift; // !
end
'h1E: begin
keys[7][6] <= release_btn | shift; // 2
keys[8][1] <= release_btn | ~shift; // @
end
'h26: begin
keys[6][7] <= release_btn | shift; // 3
keys[0][1] <= release_btn | ~shift; // #
end
'h25: begin
keys[4][6] <= release_btn | shift; // 4
keys[1][1] <= release_btn | ~shift; // $
end
'h2E: begin
keys[5][6] <= release_btn | shift; // 5
keys[0][2] <= release_btn | ~shift; // %
end
'h36: begin
keys[4][7] <= release_btn | shift; // 6
keys[2][5] <= release_btn | ~shift; // ^
end
'h3D: begin
keys[2][6] <= release_btn | shift; // 7
keys[0][3] <= release_btn | ~shift; // &
end
'h3E: begin
keys[3][6] <= release_btn | shift; // 8
keys[5][7] <= release_btn | ~shift; // *
end
'h46: begin
keys[2][7] <= release_btn | shift; // 9
keys[0][4] <= release_btn | ~shift; // (
end
'h45: begin
keys[8][6] <= release_btn | shift; // 0
keys[1][4] <= release_btn | ~shift; // )
end
'h41: begin
keys[7][3] <= release_btn | shift; // ,
keys[9][3] <= release_btn | ~shift; // <
end
'h49: begin
keys[9][6] <= release_btn | shift; // .
keys[8][4] <= release_btn | ~shift; // >
end
'h4A: begin
keys[3][7] <= release_btn | shift; // /
keys[7][4] <= release_btn | ~shift; // ?
end
'h4C: begin
keys[6][4] <= release_btn | shift; // ;
keys[5][4] <= release_btn | ~shift; // :
end
'h4E: begin
keys[8][7] <= release_btn | shift; // -
keys[0][5] <= release_btn | ~shift; // _
end
'h52: begin
keys[1][2] <= release_btn | shift; // '
keys[1][0] <= release_btn | ~shift; // "
end
'h55: begin
keys[9][7] <= release_btn | shift; // =
keys[7][7] <= release_btn | ~shift; // +
end
default:;
endcase
end
end
always @(posedge clk) begin
reg old_reset = 0;
reg action = 0;
old_reset <= reset;
input_strobe <= 0;
if(~old_reset & reset)begin
prev_clk <= 0;
shift_reg <= 12'hFFF;
end else begin
prev_clk <= {ps2_kbd_clk,prev_clk[3:1]};
if(prev_clk == 1) begin
if (kdata[11] & ^kdata[10:2] & ~kdata[1] & kdata[0]) begin
shift_reg <= 12'hFFF;
if (kcode == 8'he0) ;
// Extended key code follows
else if (kcode == 8'hf0)
// Release code follows
action <= 1;
else begin
// Cancel extended/release flags for next time
action <= 0;
release_btn <= action;
code <= kcode;
input_strobe <= 1;
end
end else begin
shift_reg <= kdata;
end
end
end
end
endmodule

View File

@@ -1,491 +0,0 @@
//
// mist_io.v
//
// mist_io for the MiST board
// http://code.google.com/p/mist-board/
//
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////
//
// Use buffer to access SD card. It's time-critical part.
// Made module synchroneous with 2 clock domains: clk_sys and SPI_SCK
// (Sorgelig)
//
// for synchronous projects default value for PS2DIV is fine for any frequency of system clock.
// clk_ps2 = clk_sys/(PS2DIV*2)
//
module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
(
// parameter STRLEN and the actual length of conf_str have to match
input [(8*STRLEN)-1:0] conf_str,
// Global clock. It should be around 100MHz (higher is better).
input clk_sys,
// Global SPI clock from ARM. 24MHz
input SPI_SCK,
input CONF_DATA0,
input SPI_SS2,
output SPI_DO,
input SPI_DI,
output reg [7:0] joystick_0,
output reg [7:0] joystick_1,
output reg [15:0] joystick_analog_0,
output reg [15:0] joystick_analog_1,
output [1:0] buttons,
output [1:0] switches,
output scandoubler_disable,
output ypbpr,
output reg [31:0] status,
// SD config
input sd_conf,
input sd_sdhc,
output img_mounted, // signaling that new image has been mounted
output reg [31:0] img_size, // size of image in bytes
// SD block level access
input [31:0] sd_lba,
input sd_rd,
input sd_wr,
output reg sd_ack,
output reg sd_ack_conf,
// SD byte level access. Signals for 2-PORT altsyncram.
output reg [8:0] sd_buff_addr,
output reg [7:0] sd_buff_dout,
input [7:0] sd_buff_din,
output reg sd_buff_wr,
// ps2 keyboard emulation
output ps2_kbd_clk,
output reg ps2_kbd_data,
output ps2_mouse_clk,
output reg ps2_mouse_data,
input ps2_caps_led,
// ARM -> FPGA download
output reg ioctl_download = 0, // signal indicating an active download
output reg [7:0] ioctl_index, // menu index used to upload the file
output ioctl_wr,
output reg [24:0] ioctl_addr,
output reg [7:0] ioctl_dout
);
reg [7:0] b_data;
reg [6:0] sbuf;
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [9:0] byte_cnt; // counts bytes
reg [7:0] but_sw;
reg [2:0] stick_idx;
reg mount_strobe = 0;
assign img_mounted = mount_strobe;
assign buttons = but_sw[1:0];
assign switches = but_sw[3:2];
assign scandoubler_disable = but_sw[4];
assign ypbpr = but_sw[5];
wire [7:0] spi_dout = { sbuf, SPI_DI};
// this variant of user_io is for 8 bit cores (type == a4) only
wire [7:0] core_type = 8'ha4;
// command byte read by the io controller
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
reg spi_do;
assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do;
wire [7:0] kbd_led = { 2'b01, 4'b0000, ps2_caps_led, 1'b1};
// drive MISO only when transmitting core id
always@(negedge SPI_SCK) begin
if(!CONF_DATA0) begin
// first byte returned is always core type, further bytes are
// command dependent
if(byte_cnt == 0) begin
spi_do <= core_type[~bit_cnt];
end else begin
case(cmd)
// reading config string
8'h14: begin
// returning a byte from string
if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
else spi_do <= 0;
end
// reading sd card status
8'h16: begin
if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt];
else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}];
else spi_do <= 0;
end
// reading sd card write data
8'h18:
spi_do <= b_data[~bit_cnt];
// reading keyboard LED status
8'h1f:
spi_do <= kbd_led[~bit_cnt];
default:
spi_do <= 0;
endcase
end
end
end
reg b_wr2,b_wr3;
always @(negedge clk_sys) begin
b_wr3 <= b_wr2;
sd_buff_wr <= b_wr3;
end
// SPI receiver
always@(posedge SPI_SCK or posedge CONF_DATA0) begin
if(CONF_DATA0) begin
b_wr2 <= 0;
bit_cnt <= 0;
byte_cnt <= 0;
sd_ack <= 0;
sd_ack_conf <= 0;
end else begin
b_wr2 <= 0;
sbuf <= spi_dout[6:0];
bit_cnt <= bit_cnt + 1'd1;
if(bit_cnt == 5) begin
if (byte_cnt == 0) sd_buff_addr <= 0;
if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1;
if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0;
end
// finished reading command byte
if(bit_cnt == 7) begin
if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1;
if(byte_cnt == 0) begin
cmd <= spi_dout;
if(spi_dout == 8'h19) begin
sd_ack_conf <= 1;
sd_buff_addr <= 0;
end
if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin
sd_ack <= 1;
sd_buff_addr <= 0;
end
if(spi_dout == 8'h18) b_data <= sd_buff_din;
mount_strobe <= 0;
end else begin
case(cmd)
// buttons and switches
8'h01: but_sw <= spi_dout;
8'h02: joystick_0 <= spi_dout;
8'h03: joystick_1 <= spi_dout;
// store incoming ps2 mouse bytes
8'h04: begin
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout;
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
end
// store incoming ps2 keyboard bytes
8'h05: begin
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout;
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
end
8'h15: status[7:0] <= spi_dout;
// send SD config IO -> FPGA
// flag that download begins
// sd card knows data is config if sd_dout_strobe is asserted
// with sd_ack still being inactive (low)
8'h19,
// send sector IO -> FPGA
// flag that download begins
8'h17: begin
sd_buff_dout <= spi_dout;
b_wr2 <= 1;
end
8'h18: b_data <= sd_buff_din;
// joystick analog
8'h1a: begin
// first byte is joystick index
if(byte_cnt == 1) stick_idx <= spi_dout[2:0];
else if(byte_cnt == 2) begin
// second byte is x axis
if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout;
else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout;
end else if(byte_cnt == 3) begin
// third byte is y axis
if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout;
else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout;
end
end
// notify image selection
8'h1c: mount_strobe <= 1;
// send image info
8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout;
// status, 32bit version
8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout;
default: ;
endcase
end
end
end
end
/////////////////////////////// PS2 ///////////////////////////////
// 8 byte fifos to store ps2 bytes
localparam PS2_FIFO_BITS = 3;
reg clk_ps2;
always @(negedge clk_sys) begin
integer cnt;
cnt <= cnt + 1'd1;
if(cnt == PS2DIV) begin
clk_ps2 <= ~clk_ps2;
cnt <= 0;
end
end
// keyboard
reg [7:0] ps2_kbd_fifo[1<<PS2_FIFO_BITS];
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
// ps2 transmitter state machine
reg [3:0] ps2_kbd_tx_state;
reg [7:0] ps2_kbd_tx_byte;
reg ps2_kbd_parity;
assign ps2_kbd_clk = clk_ps2 || (ps2_kbd_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_kbd_r_inc;
always@(posedge clk_sys) begin
reg old_clk;
old_clk <= clk_ps2;
if(~old_clk & clk_ps2) begin
ps2_kbd_r_inc <= 0;
if(ps2_kbd_r_inc) ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
// transmitter is idle?
if(ps2_kbd_tx_state == 0) begin
// data in fifo present?
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
// load tx register from fifo
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
ps2_kbd_r_inc <= 1;
// reset parity
ps2_kbd_parity <= 1;
// start transmitter
ps2_kbd_tx_state <= 1;
// put start bit on data line
ps2_kbd_data <= 0; // start bit is 0
end
end else begin
// transmission of 8 data bits
if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
if(ps2_kbd_tx_byte[0])
ps2_kbd_parity <= !ps2_kbd_parity;
end
// transmission of parity
if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity;
// transmission of stop bit
if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1
// advance state machine
if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1;
else ps2_kbd_tx_state <= 0;
end
end
end
// mouse
reg [7:0] ps2_mouse_fifo[1<<PS2_FIFO_BITS];
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
// ps2 transmitter state machine
reg [3:0] ps2_mouse_tx_state;
reg [7:0] ps2_mouse_tx_byte;
reg ps2_mouse_parity;
assign ps2_mouse_clk = clk_ps2 || (ps2_mouse_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_mouse_r_inc;
always@(posedge clk_sys) begin
reg old_clk;
old_clk <= clk_ps2;
if(~old_clk & clk_ps2) begin
ps2_mouse_r_inc <= 0;
if(ps2_mouse_r_inc) ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
// transmitter is idle?
if(ps2_mouse_tx_state == 0) begin
// data in fifo present?
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
// load tx register from fifo
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
ps2_mouse_r_inc <= 1;
// reset parity
ps2_mouse_parity <= 1;
// start transmitter
ps2_mouse_tx_state <= 1;
// put start bit on data line
ps2_mouse_data <= 0; // start bit is 0
end
end else begin
// transmission of 8 data bits
if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin
ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits
ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down
if(ps2_mouse_tx_byte[0])
ps2_mouse_parity <= !ps2_mouse_parity;
end
// transmission of parity
if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity;
// transmission of stop bit
if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1
// advance state machine
if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1;
else ps2_mouse_tx_state <= 0;
end
end
end
/////////////////////////////// DOWNLOADING ///////////////////////////////
reg [7:0] data_w;
reg [24:0] addr_w;
reg rclk = 0;
localparam UIO_FILE_TX = 8'h53;
localparam UIO_FILE_TX_DAT = 8'h54;
localparam UIO_FILE_INDEX = 8'h55;
// data_io has its own SPI interface to the io controller
always@(posedge SPI_SCK, posedge SPI_SS2) begin
reg [6:0] sbuf;
reg [7:0] cmd;
reg [4:0] cnt;
reg [24:0] addr;
if(SPI_SS2) cnt <= 0;
else begin
rclk <= 0;
// don't shift in last bit. It is evaluated directly
// when writing to ram
if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI};
// increase target address after write
if(rclk) addr <= addr + 1'd1;
// count 0-7 8-15 8-15 ...
if(cnt < 15) cnt <= cnt + 1'd1;
else cnt <= 8;
// finished command byte
if(cnt == 7) cmd <= {sbuf, SPI_DI};
// prepare/end transmission
if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
// prepare
if(SPI_DI) begin
addr <= 0;
ioctl_download <= 1;
end else begin
addr_w <= addr;
ioctl_download <= 0;
end
end
// command 0x54: UIO_FILE_TX
if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin
addr_w <= addr;
data_w <= {sbuf, SPI_DI};
rclk <= 1;
end
// expose file (menu) index
if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI};
end
end
assign ioctl_wr = |ioctl_wrd;
reg [1:0] ioctl_wrd;
always@(negedge clk_sys) begin
reg rclkD, rclkD2;
rclkD <= rclk;
rclkD2 <= rclkD;
ioctl_wrd<= {ioctl_wrd[0],1'b0};
if(rclkD & ~rclkD2) begin
ioctl_dout <= data_w;
ioctl_addr <= addr_w;
ioctl_wrd <= 2'b11;
end
end
endmodule

View File

@@ -1,179 +0,0 @@
// A simple OSD implementation. Can be hooked up between a cores
// VGA output and the physical VGA pins
module osd (
// OSDs pixel clock, should be synchronous to cores pixel clock to
// avoid jitter.
input clk_sys,
// SPI interface
input SPI_SCK,
input SPI_SS3,
input SPI_DI,
// VGA signals coming from core
input [5:0] R_in,
input [5:0] G_in,
input [5:0] B_in,
input HSync,
input VSync,
// VGA signals going to video connector
output [5:0] R_out,
output [5:0] G_out,
output [5:0] B_out
);
parameter OSD_X_OFFSET = 10'd0;
parameter OSD_Y_OFFSET = 10'd0;
parameter OSD_COLOR = 3'd0;
localparam OSD_WIDTH = 10'd256;
localparam OSD_HEIGHT = 10'd128;
// *********************************************************************************
// spi client
// *********************************************************************************
// this core supports only the display related OSD commands
// of the minimig
reg osd_enable;
(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself
// the OSD has its own SPI interface to the io controller
always@(posedge SPI_SCK, posedge SPI_SS3) begin
reg [4:0] cnt;
reg [10:0] bcnt;
reg [7:0] sbuf;
reg [7:0] cmd;
if(SPI_SS3) begin
cnt <= 0;
bcnt <= 0;
end else begin
sbuf <= {sbuf[6:0], SPI_DI};
// 0:7 is command, rest payload
if(cnt < 15) cnt <= cnt + 1'd1;
else cnt <= 8;
if(cnt == 7) begin
cmd <= {sbuf[6:0], SPI_DI};
// lower three command bits are line address
bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI;
end
// command 0x20: OSDCMDWRITE
if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI};
bcnt <= bcnt + 1'd1;
end
end
end
// *********************************************************************************
// video timing and sync polarity anaylsis
// *********************************************************************************
// horizontal counter
reg [9:0] h_cnt;
reg [9:0] hs_low, hs_high;
wire hs_pol = hs_high < hs_low;
wire [9:0] dsp_width = hs_pol ? hs_low : hs_high;
// vertical counter
reg [9:0] v_cnt;
reg [9:0] vs_low, vs_high;
wire vs_pol = vs_high < vs_low;
wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
wire doublescan = (dsp_height>350);
reg ce_pix;
always @(negedge clk_sys) begin
integer cnt = 0;
integer pixsz, pixcnt;
reg hs;
cnt <= cnt + 1;
hs <= HSync;
pixcnt <= pixcnt + 1;
if(pixcnt == pixsz) pixcnt <= 0;
ce_pix <= !pixcnt;
if(hs && ~HSync) begin
cnt <= 0;
pixsz <= (cnt >> 9) - 1;
pixcnt <= 0;
ce_pix <= 1;
end
end
always @(posedge clk_sys) begin
reg hsD, hsD2;
reg vsD, vsD2;
if(ce_pix) begin
// bring hsync into local clock domain
hsD <= HSync;
hsD2 <= hsD;
// falling edge of HSync
if(!hsD && hsD2) begin
h_cnt <= 0;
hs_high <= h_cnt;
end
// rising edge of HSync
else if(hsD && !hsD2) begin
h_cnt <= 0;
hs_low <= h_cnt;
v_cnt <= v_cnt + 1'd1;
end else begin
h_cnt <= h_cnt + 1'd1;
end
vsD <= VSync;
vsD2 <= vsD;
// falling edge of VSync
if(!vsD && vsD2) begin
v_cnt <= 0;
vs_high <= v_cnt;
end
// rising edge of VSync
else if(vsD && !vsD2) begin
v_cnt <= 0;
vs_low <= v_cnt;
end
end
end
// area in which OSD is being displayed
wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<<doublescan))>> 1) + OSD_Y_OFFSET;
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
wire osd_de = osd_enable &&
(HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) &&
(VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
reg [7:0] osd_byte;
always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}];
wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]};
endmodule

View File

@@ -1,186 +0,0 @@
`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////////////
//
// Engineer: Thomas Skibo
//
// Create Date: Sep 23, 2011
//
// Module Name: pet2001hw
//
// Description: Encapsulate all Pet hardware except cpu.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011, Thomas Skibo. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * The names of contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Thomas Skibo OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
module pet2001hw
(
input [15:0] addr, // CPU Interface
input [7:0] data_in,
output reg [7:0] data_out,
input we,
output irq,
output pix,
output HSync,
output VSync,
output [3:0] keyrow, // Keyboard
input [7:0] keyin,
output cass_motor_n, // Cassette
output cass_write,
input cass_sense_n,
input cass_read,
output audio, // CB2 audio
input [13:0] dma_addr,
input [7:0] dma_din,
output [7:0] dma_dout,
input dma_we,
input clk_speed,
input clk_stop,
input diag_l,
input clk,
input ce_7mp,
input ce_7mn,
input ce_1m,
input reset
);
/////////////////////////////////////////////////////////////
// Pet ROMS incuding character ROM. Character data is read
// out second port. This brings total ROM to 16K which is
// easy to arrange.
/////////////////////////////////////////////////////////////
wire [7:0] rom_data;
wire [10:0] charaddr;
wire [7:0] chardata;
pet2001rom rom
(
.q_a(rom_data),
.q_b(chardata),
.address_a(addr[13:0]),
.address_b({3'b101,charaddr}),
.clock(clk)
);
//////////////////////////////////////////////////////////////
// Pet RAM and video RAM. Video RAM is dual ported.
//////////////////////////////////////////////////////////////
wire [7:0] ram_data;
wire [7:0] vram_data;
wire [7:0] video_data;
wire [10:0] video_addr;
wire ram_we = we && (addr[15:14] == 2'b00);
wire vram_we = we && (addr[15:11] == 5'b1000_0);
pet2001ram ram
(
.clock(clk),
.q_a(ram_data),
.data_a(data_in),
.address_a(addr[13:0]),
.wren_a(ram_we),
.q_b(dma_dout),
.data_b(dma_din),
.address_b(dma_addr),
.wren_b(dma_we)
);
pet2001vram vidram
(
.clock(clk),
.address_a(addr[10:0]),
.data_a(data_in),
.wren_a(vram_we),
.q_a(vram_data),
.address_b(video_addr),
.data_b(0),
.wren_b(0),
.q_b(video_data)
);
//////////////////////////////////////
// Video hardware.
//////////////////////////////////////
wire video_on; // signal indicating VGA is scanning visible
// rows. Used to generate tick interrupts.
wire video_blank; // blank screen during scrolling
wire video_gfx; // display graphic characters vs. lower-case
pet2001video vid(.*);
////////////////////////////////////////////////////////
// I/O hardware
////////////////////////////////////////////////////////
wire [7:0] io_read_data;
wire io_we = we && (addr[15:11] == 5'b1110_1);
pet2001io io
(
.*,
.ce(ce_1m),
.data_out(io_read_data),
.data_in(data_in),
.addr(addr[10:0]),
.we(io_we),
.video_sync(video_on)
);
/////////////////////////////////////
// Read data mux (to CPU)
/////////////////////////////////////
always @(*)
casex(addr[15:11])
5'b1111_x: // F000-FFFF
data_out = rom_data;
5'b1110_1: // E800-EFFF
data_out = io_read_data;
5'b1110_0: // E000-E7FF
data_out = rom_data;
5'b110x_x: // C000-DFFF
data_out = rom_data;
5'b1000_0: // 8000-87FF
data_out = vram_data;
5'b00xx_x: // 0000-3FFF
data_out = ram_data;
default:
data_out = 8'h55;
endcase
endmodule // pet2001hw

View File

@@ -1,208 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////
//
// Engineer: Thomas Skibo
//
// Create Date: Sep 24, 2011
//
// Module Name: pet2001io
//
// Description:
// I/O devices for Pet emulator. Includes two PIAs and a VIA and a
// module that converts a PS2 keyboard into a PET keyboard.
//
// I/O is mapped into region 0xE800-0xEFFF.
//
// 0xE810-0xE813 PIA1
// 0xE820-0xE823 PIA2
// 0xE840-0xE84F VIA
//
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011, Thomas Skibo. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * The names of contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Thomas Skibo OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
module pet2001io
(
output reg [7:0] data_out, // CPU interface
input [7:0] data_in,
input [10:0] addr,
input we,
output irq,
output [3:0] keyrow, // Keyboard
input [7:0] keyin,
output video_blank, // Video controls
output video_gfx,
input video_sync,
output cass_motor_n, // Cassette #1 interface
output cass_write,
input cass_sense_n,
input cass_read,
output audio, // CB2 audio
input diag_l, // diag jumper input
input ce,
input clk,
input reset
);
//delay ce for io for stability.
reg strobe_io;
always @(negedge clk) strobe_io <= ce;
/////////////////////////// 6520 PIA1 ////////////////////////////////////
//
wire pia1_strobe = strobe_io && (addr[10:2] == 9'b000_0001_00);
wire [7:0] pia1_data_out;
wire pia1_irq;
wire [7:0] pia1_porta_out;
wire [7:0] pia1_porta_in = {diag_l, 2'b00, cass_sense_n, 4'b0000};
wire pia1_ca1_in = !cass_read;
wire pia1_ca2_out;
pia6520 pia1
(
.data_out(pia1_data_out),
.data_in(data_in),
.addr(addr[1:0]),
.strobe(pia1_strobe),
.we(we),
.irq(pia1_irq),
.porta_out(pia1_porta_out),
.porta_in(pia1_porta_in),
.portb_out(),
.portb_in(keyin),
.ca1_in(pia1_ca1_in),
.ca2_out(pia1_ca2_out),
.ca2_in(1'b0),
.cb1_in(video_sync),
.cb2_out(cass_motor_n),
.cb2_in(1'b0),
.clk(clk),
.reset(reset)
);
assign video_blank = !pia1_ca2_out;
assign keyrow = pia1_porta_out[3:0];
////////////////////////// 6520 PIA2 ////////////////////////////////////
// (does nothing for now)
wire pia2_strobe = strobe_io && (addr[10:2] == 9'b000_0010_00);
wire [7:0] pia2_data_out;
wire pia2_irq;
pia6520 pia2
(
.data_out(pia2_data_out),
.data_in(data_in),
.addr(addr[1:0]),
.strobe(pia2_strobe),
.we(we),
.irq(pia2_irq),
.porta_out(),
.porta_in(8'h00),
.portb_out(),
.portb_in(8'h00),
.ca1_in(1'b0),
.ca2_out(),
.ca2_in(1'b0),
.cb1_in(1'b0),
.cb2_out(),
.cb2_in(1'b0),
.clk(clk),
.reset(reset)
);
/////////////////////////// 6522 VIA ////////////////////////////////////
//
wire via_strobe = strobe_io && (addr[10:4] == 7'b000_0100);
wire [7:0] via_data_out;
wire via_irq;
wire [7:0] via_portb_out;
wire [7:0] via_portb_in = {2'b00, video_sync, 5'b0_0000};
via6522 via
(
.data_out(via_data_out),
.data_in(data_in),
.addr(addr[3:0]),
.strobe(via_strobe),
.we(we),
.irq(via_irq),
.porta_out(),
.porta_in(8'h00),
.portb_out(via_portb_out),
.portb_in(via_portb_in),
.ca1_in(1'b0),
.ca2_out(video_gfx),
.ca2_in(1'b0),
.cb1_out(),
.cb1_in(1'b0),
.cb2_out(audio),
.cb2_in(1'b0),
.ce(ce),
.clk(clk),
.reset(reset)
);
assign cass_write = via_portb_out[3];
/////////////// Read data mux /////////////////////////
// register I/O stuff, therefore RDY must be delayed a cycle!
//
always @(posedge clk)
casex (addr[10:2])
9'b000_0001_00: data_out <= pia1_data_out;
9'b000_0010_00: data_out <= pia2_data_out;
9'b000_0100_xx: data_out <= via_data_out;
default: data_out <= 8'hXX;
endcase
assign irq = pia1_irq || pia2_irq || via_irq;
endmodule // pet2001io

View File

@@ -1,242 +0,0 @@
// megafunction wizard: %RAM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: pet2001ram.v
// Megafunction Name(s):
// altsyncram
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.4 Build 182 03/12/2014 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2014 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.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pet2001ram (
address_a,
address_b,
clock,
data_a,
data_b,
wren_a,
wren_b,
q_a,
q_b);
input [13:0] address_a;
input [13:0] address_b;
input clock;
input [7:0] data_a;
input [7:0] data_b;
input wren_a;
input wren_b;
output [7:0] q_a;
output [7:0] q_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 clock;
tri0 wren_a;
tri0 wren_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [7:0] sub_wire0;
wire [7:0] sub_wire1;
wire [7:0] q_a = sub_wire0[7:0];
wire [7:0] q_b = sub_wire1[7:0];
altsyncram altsyncram_component (
.clock0 (clock),
.wren_a (wren_a),
.address_b (address_b),
.data_b (data_b),
.wren_b (wren_b),
.address_a (address_a),
.data_a (data_a),
.q_a (sub_wire0),
.q_b (sub_wire1),
.aclr0 (1'b0),
.aclr1 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.eccstatus (),
.rden_a (1'b1),
.rden_b (1'b1));
defparam
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_a = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.indata_reg_b = "CLOCK0",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 16384,
altsyncram_component.numwords_b = 16384,
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
altsyncram_component.outdata_aclr_a = "NONE",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_a = "UNREGISTERED",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
altsyncram_component.widthad_a = 14,
altsyncram_component.widthad_b = 14,
altsyncram_component.width_a = 8,
altsyncram_component.width_b = 8,
altsyncram_component.width_byteena_a = 1,
altsyncram_component.width_byteena_b = 1,
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
endmodule
// ============================================================
// 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 "1"
// 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: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// 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 "131072"
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING ""
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
// 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 "0"
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
// 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 "1"
// 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_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_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "16384"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
// 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: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "14"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: USED_PORT: address_a 0 0 14 0 INPUT NODEFVAL "address_a[13..0]"
// Retrieval info: USED_PORT: address_b 0 0 14 0 INPUT NODEFVAL "address_b[13..0]"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..0]"
// Retrieval info: USED_PORT: data_b 0 0 8 0 INPUT NODEFVAL "data_b[7..0]"
// Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
// Retrieval info: USED_PORT: q_b 0 0 8 0 OUTPUT NODEFVAL "q_b[7..0]"
// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
// Retrieval info: CONNECT: @address_a 0 0 14 0 address_a 0 0 14 0
// Retrieval info: CONNECT: @address_b 0 0 14 0 address_b 0 0 14 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 0
// Retrieval info: CONNECT: @data_b 0 0 8 0 data_b 0 0 8 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
// Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
// Retrieval info: CONNECT: q_b 0 0 8 0 @q_b 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001ram_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@@ -1,228 +0,0 @@
// megafunction wizard: %ROM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: pet2001rom.v
// Megafunction Name(s):
// altsyncram
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.4 Build 182 03/12/2014 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2014 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.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pet2001rom (
address_a,
address_b,
clock,
q_a,
q_b);
input [13:0] address_a;
input [13:0] address_b;
input clock;
output [7:0] q_a;
output [7:0] q_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [7:0] sub_wire0;
wire [7:0] sub_wire1;
wire sub_wire2 = 1'h0;
wire [7:0] sub_wire3 = 8'h0;
wire [7:0] q_b = sub_wire0[7:0];
wire [7:0] q_a = sub_wire1[7:0];
altsyncram altsyncram_component (
.clock0 (clock),
.wren_a (sub_wire2),
.address_b (address_b),
.data_b (sub_wire3),
.wren_b (sub_wire2),
.address_a (address_a),
.data_a (sub_wire3),
.q_b (sub_wire0),
.q_a (sub_wire1)
// synopsys translate_off
,
.aclr0 (),
.aclr1 (),
.addressstall_a (),
.addressstall_b (),
.byteena_a (),
.byteena_b (),
.clock1 (),
.clocken0 (),
.clocken1 (),
.clocken2 (),
.clocken3 (),
.eccstatus (),
.rden_a (),
.rden_b ()
// synopsys translate_on
);
defparam
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_a = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.indata_reg_b = "CLOCK0",
altsyncram_component.init_file = "./roms/Pet2001_RomType2.mif",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 16384,
altsyncram_component.numwords_b = 16384,
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
altsyncram_component.outdata_aclr_a = "NONE",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_a = "UNREGISTERED",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.widthad_a = 14,
altsyncram_component.widthad_b = 14,
altsyncram_component.width_a = 8,
altsyncram_component.width_b = 8,
altsyncram_component.width_byteena_a = 1,
altsyncram_component.width_byteena_b = 1,
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
endmodule
// ============================================================
// 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 "1"
// 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: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// 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 "131072"
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING "./roms/Pet2001_RomType2.mif"
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
// 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: REGdata NUMERIC "1"
// Retrieval info: PRIVATE: REGq NUMERIC "0"
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
// 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 "1"
// 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_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_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: INIT_FILE STRING "./roms/Pet2001_RomType2.mif"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "16384"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "14"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: USED_PORT: address_a 0 0 14 0 INPUT NODEFVAL "address_a[13..0]"
// Retrieval info: USED_PORT: address_b 0 0 14 0 INPUT NODEFVAL "address_b[13..0]"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
// Retrieval info: USED_PORT: q_b 0 0 8 0 OUTPUT NODEFVAL "q_b[7..0]"
// Retrieval info: CONNECT: @address_a 0 0 14 0 address_a 0 0 14 0
// Retrieval info: CONNECT: @address_b 0 0 14 0 address_b 0 0 14 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 8 0 GND 0 0 8 0
// Retrieval info: CONNECT: @data_b 0 0 8 0 GND 0 0 8 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 GND 0 0 0 0
// Retrieval info: CONNECT: @wren_b 0 0 0 0 GND 0 0 0 0
// Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
// Retrieval info: CONNECT: q_b 0 0 8 0 @q_b 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001rom_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@@ -1,60 +0,0 @@
`timescale 1ns / 1ps
module pet2001video
(
output pix,
output reg HSync,
output reg VSync,
output [10:0] video_addr, // Video RAM intf
input [7:0] video_data,
output [10:0] charaddr, // char rom intf
input [7:0] chardata,
output video_on, // control sigs
input video_blank,
input video_gfx,
input clk,
input ce_7mp,
input ce_7mn
);
assign video_on = (vc < 200);
assign video_addr = {vc[8:3], 5'b00000}+{vc[8:3], 3'b000}+hc[8:3];
assign charaddr = {video_gfx, video_data[6:0], vc[2:0]};
reg [8:0] hc;
reg [8:0] vc;
always @(posedge clk) begin
if(ce_7mp) begin
hc <= hc + 1'd1;
if(hc == 447) begin
hc <=0;
vc <= vc + 1'd1;
if(vc == 261) vc <= 0;
end
end
if(ce_7mn) begin
if(hc == 358) HSync <= 1;
if(hc == 391) HSync <= 0;
if(vc == 225) VSync <= 1;
if(vc == 234) VSync <= 0;
end
end
reg [7:0] vdata;
reg inv;
assign pix = (vdata[7] ^ inv) & ~video_blank;
always @(posedge clk) begin
if(ce_7mn) begin
if(!hc[2:0]) {inv, vdata} <= ((hc<320) && (vc<200)) ? {video_data[7], chardata} : 9'd0;
else vdata <= {vdata[6:0], 1'b0};
end
end
endmodule // pet2001video

View File

@@ -1,242 +0,0 @@
// megafunction wizard: %RAM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: pet2001vram.v
// Megafunction Name(s):
// altsyncram
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.4 Build 182 03/12/2014 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2014 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.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pet2001vram (
address_a,
address_b,
clock,
data_a,
data_b,
wren_a,
wren_b,
q_a,
q_b);
input [10:0] address_a;
input [10:0] address_b;
input clock;
input [7:0] data_a;
input [7:0] data_b;
input wren_a;
input wren_b;
output [7:0] q_a;
output [7:0] q_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 clock;
tri0 wren_a;
tri0 wren_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [7:0] sub_wire0;
wire [7:0] sub_wire1;
wire [7:0] q_a = sub_wire0[7:0];
wire [7:0] q_b = sub_wire1[7:0];
altsyncram altsyncram_component (
.clock0 (clock),
.wren_a (wren_a),
.address_b (address_b),
.data_b (data_b),
.wren_b (wren_b),
.address_a (address_a),
.data_a (data_a),
.q_a (sub_wire0),
.q_b (sub_wire1),
.aclr0 (1'b0),
.aclr1 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.eccstatus (),
.rden_a (1'b1),
.rden_b (1'b1));
defparam
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_a = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.indata_reg_b = "CLOCK0",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 2048,
altsyncram_component.numwords_b = 2048,
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
altsyncram_component.outdata_aclr_a = "NONE",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_a = "UNREGISTERED",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
altsyncram_component.widthad_a = 11,
altsyncram_component.widthad_b = 11,
altsyncram_component.width_a = 8,
altsyncram_component.width_b = 8,
altsyncram_component.width_byteena_a = 1,
altsyncram_component.width_byteena_b = 1,
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
endmodule
// ============================================================
// 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 "1"
// 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: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// 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 "16384"
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING ""
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
// 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 "0"
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
// 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 "1"
// 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_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_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "2048"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
// 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: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "11"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: USED_PORT: address_a 0 0 11 0 INPUT NODEFVAL "address_a[10..0]"
// Retrieval info: USED_PORT: address_b 0 0 11 0 INPUT NODEFVAL "address_b[10..0]"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..0]"
// Retrieval info: USED_PORT: data_b 0 0 8 0 INPUT NODEFVAL "data_b[7..0]"
// Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
// Retrieval info: USED_PORT: q_b 0 0 8 0 OUTPUT NODEFVAL "q_b[7..0]"
// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
// Retrieval info: CONNECT: @address_a 0 0 11 0 address_a 0 0 11 0
// Retrieval info: CONNECT: @address_b 0 0 11 0 address_b 0 0 11 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 0
// Retrieval info: CONNECT: @data_b 0 0 8 0 data_b 0 0 8 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
// Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
// Retrieval info: CONNECT: q_b 0 0 8 0 @q_b 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pet2001vram_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@@ -1,230 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////
//
// Engineer: Thomas Skibo
//
// Create Date: Sep 24, 2011
//
// Module Name: pia6520
//
// Description:
//
// A simple implementation of the 6520 Peripheral Interface Adapter (PIA).
// Tri-state lines aren't used. Instead, All PIA I/O signals have
// seperate "in" and "out" signals. Wire or ignore appropriately.
//
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011, Thomas Skibo. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * The names of contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Thomas Skibo OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
module pia6520
(
output reg [7:0] data_out, // cpu interface
input [7:0] data_in,
input [1:0] addr,
input strobe,
input we,
output irq,
output reg [7:0] porta_out,
input [7:0] porta_in,
output reg [7:0] portb_out,
input [7:0] portb_in,
input ca1_in,
output reg ca2_out,
input ca2_in,
input cb1_in,
output reg cb2_out,
input cb2_in,
input clk,
input reset
);
reg [7:0] ddra;
reg [5:0] cra;
reg irqa1;
reg irqa2;
reg [7:0] ddrb;
reg [5:0] crb;
reg irqb1;
reg irqb2;
// Register address offsets
parameter [1:0]
ADDR_PORTA = 2'b00,
ADDR_CRA = 2'b01,
ADDR_PORTB = 2'b10,
ADDR_CRB = 2'b11;
wire wr_strobe = strobe && we;
wire rd_strobe = strobe && !we;
wire porta_rd_strobe = rd_strobe && addr == ADDR_PORTA;
wire portb_rd_strobe = rd_strobe && addr == ADDR_PORTB;
wire portb_wr_strobe = wr_strobe && addr == ADDR_PORTB;
// Implement CRA[5:0]
always @(posedge clk) begin
if (reset) cra <= 6'b00_0000;
else if (wr_strobe && addr == ADDR_CRA) cra <= data_in[5:0];
end
// Implement CRB[5:0]
always @(posedge clk) begin
if (reset) crb <= 6'b00_0000;
else if (wr_strobe && addr == ADDR_CRB) crb <= data_in[5:0];
end
// Implement PORTA (out)
always @(posedge clk) begin
if (reset) porta_out <= 8'h00;
else if (wr_strobe && addr == ADDR_PORTA && cra[2]) porta_out <= data_in;
end
// Implement DDRA
always @(posedge clk) begin
if (reset) ddra <= 8'h00;
else if (wr_strobe && addr == ADDR_PORTA && !cra[2]) ddra <= data_in;
end
// Implement PORTB (out)
always @(posedge clk) begin
if (reset) portb_out <= 8'h00;
else if (wr_strobe && addr == ADDR_PORTB && crb[2]) portb_out <= data_in;
end
// Implement DDRB
always @(posedge clk) begin
if (reset) ddrb <= 8'h00;
else if (wr_strobe && addr == ADDR_PORTB && !crb[2]) ddrb <= data_in;
end
////////////////////////////////////////////////////////
// IRQA logic
// register ca1_in and ca2_in to detect transitions.
reg ca1_in_1;
reg ca2_in_1;
always @(posedge clk) begin
ca1_in_1 <= ca1_in;
ca2_in_1 <= ca2_in;
end
// detect "active" transitions
wire ca1_act_trans = ((ca1_in && !ca1_in_1 && cra[1]) || (!ca1_in && ca1_in_1 && !cra[1]));
wire ca2_act_trans = ((ca2_in && !ca2_in_1 && cra[4]) || (!ca2_in && ca2_in_1 && !cra[4]));
// IRQA1
always @(posedge clk) begin
if (reset || (porta_rd_strobe && !ca1_act_trans)) irqa1 <= 1'b0;
else if (ca1_act_trans) irqa1 <= 1'b1;
end
// IRQA2
always @(posedge clk) begin
if (reset || (porta_rd_strobe && !ca2_act_trans)) irqa2 <= 1'b0;
else if (ca2_act_trans && !cra[5]) irqa2 <= 1'b1;
end
////////////////////////////////////////////////////////
// IRQB logic
// register cb1_in and cb2_in to detect transitions.
reg cb1_in_1;
reg cb2_in_1;
always @(posedge clk) begin
cb1_in_1 <= cb1_in;
cb2_in_1 <= cb2_in;
end
// detect "active" transitions
wire cb1_act_trans = ((cb1_in && !cb1_in_1 && crb[1]) || (!cb1_in && cb1_in_1 && !crb[1]));
wire cb2_act_trans = ((cb2_in && !cb2_in_1 && crb[4]) || (!cb2_in && cb2_in_1 && !crb[4]));
// IRQB1
always @(posedge clk) begin
if (reset || (portb_rd_strobe && !cb1_act_trans)) irqb1 <= 1'b0;
else if (cb1_act_trans) irqb1 <= 1'b1;
end
// IRQB2
always @(posedge clk) begin
if (reset || (portb_rd_strobe && !cb2_act_trans)) irqb2 <= 1'b0;
else if (cb2_act_trans && !crb[5]) irqb2 <= 1'b1;
end
// IRQ and enable logic.
assign irq = (irqa1 && cra[0]) || (irqa2 && cra[3]) ||
(irqb1 && crb[0]) || (irqb2 && crb[3]);
///////////////////////////////////////////////////
// CA2 and CB2 output modes
always @(posedge clk) begin
case (cra[5:3])
3'b100: ca2_out <= irqa1;
3'b101: ca2_out <= !ca1_act_trans;
3'b111: ca2_out <= 1'b1;
default: ca2_out <= 1'b0;
endcase
end
reg cb2_out_r;
always @(posedge clk) begin
if (reset || (portb_wr_strobe && !cb1_act_trans)) cb2_out_r <= 1'b0;
else if (cb1_act_trans) cb2_out_r <= 1'b1;
end
always @(posedge clk) begin
case (crb[5:3])
3'b100: cb2_out <= cb2_out_r;
3'b101: cb2_out <= !portb_wr_strobe;
3'b111: cb2_out <= 1'b1;
default: cb2_out <= 1'b0;
endcase
end
///////////////////////////////////////////////////
// Read data mux
wire [7:0] porta = (porta_out & ddra) | (porta_in & ~ddra);
wire [7:0] portb = (portb_out & ddrb) | (portb_in & ~ddrb);
always @(*) begin
case (addr)
ADDR_PORTA: data_out = cra[2] ? porta : ddra;
ADDR_CRA: data_out = { irqa1, irqa2, cra };
ADDR_PORTB: data_out = crb[2] ? portb : ddrb;
ADDR_CRB: data_out = { irqb1, irqb2, crb };
endcase
end
endmodule // pia6520

View File

@@ -1,363 +0,0 @@
// megafunction wizard: %ALTPLL%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altpll
// ============================================================
// File Name: pll.v
// Megafunction Name(s):
// altpll
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.4 Build 182 03/12/2014 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2014 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.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pll (
inclk0,
c0,
c1,
c2,
locked);
input inclk0;
output c0;
output c1;
output c2;
output locked;
wire [4:0] sub_wire0;
wire sub_wire2;
wire [0:0] sub_wire7 = 1'h0;
wire [2:2] sub_wire4 = sub_wire0[2:2];
wire [0:0] sub_wire3 = sub_wire0[0:0];
wire [1:1] sub_wire1 = sub_wire0[1:1];
wire c1 = sub_wire1;
wire locked = sub_wire2;
wire c0 = sub_wire3;
wire c2 = sub_wire4;
wire sub_wire5 = inclk0;
wire [1:0] sub_wire6 = {sub_wire7, sub_wire5};
altpll altpll_component (
.inclk (sub_wire6),
.clk (sub_wire0),
.locked (sub_wire2),
.activeclock (),
.areset (1'b0),
.clkbad (),
.clkena ({6{1'b1}}),
.clkloss (),
.clkswitch (1'b0),
.configupdate (1'b0),
.enable0 (),
.enable1 (),
.extclk (),
.extclkena ({4{1'b1}}),
.fbin (1'b1),
.fbmimicbidir (),
.fbout (),
.fref (),
.icdrclk (),
.pfdena (1'b1),
.phasecounterselect ({4{1'b1}}),
.phasedone (),
.phasestep (1'b1),
.phaseupdown (1'b1),
.pllena (1'b1),
.scanaclr (1'b0),
.scanclk (1'b0),
.scanclkena (1'b1),
.scandata (1'b0),
.scandataout (),
.scandone (),
.scanread (1'b0),
.scanwrite (1'b0),
.sclkout0 (),
.sclkout1 (),
.vcooverrange (),
.vcounderrange ());
defparam
altpll_component.bandwidth_type = "AUTO",
altpll_component.clk0_divide_by = 27,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 112,
altpll_component.clk0_phase_shift = "0",
altpll_component.clk1_divide_by = 27,
altpll_component.clk1_duty_cycle = 50,
altpll_component.clk1_multiply_by = 112,
altpll_component.clk1_phase_shift = "-1488",
altpll_component.clk2_divide_by = 27,
altpll_component.clk2_duty_cycle = 50,
altpll_component.clk2_multiply_by = 56,
altpll_component.clk2_phase_shift = "0",
altpll_component.inclk0_input_frequency = 37037,
altpll_component.intended_device_family = "Cyclone III",
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
altpll_component.lpm_type = "altpll",
altpll_component.operation_mode = "NO_COMPENSATION",
altpll_component.pll_type = "AUTO",
altpll_component.port_activeclock = "PORT_UNUSED",
altpll_component.port_areset = "PORT_UNUSED",
altpll_component.port_clkbad0 = "PORT_UNUSED",
altpll_component.port_clkbad1 = "PORT_UNUSED",
altpll_component.port_clkloss = "PORT_UNUSED",
altpll_component.port_clkswitch = "PORT_UNUSED",
altpll_component.port_configupdate = "PORT_UNUSED",
altpll_component.port_fbin = "PORT_UNUSED",
altpll_component.port_inclk0 = "PORT_USED",
altpll_component.port_inclk1 = "PORT_UNUSED",
altpll_component.port_locked = "PORT_USED",
altpll_component.port_pfdena = "PORT_UNUSED",
altpll_component.port_phasecounterselect = "PORT_UNUSED",
altpll_component.port_phasedone = "PORT_UNUSED",
altpll_component.port_phasestep = "PORT_UNUSED",
altpll_component.port_phaseupdown = "PORT_UNUSED",
altpll_component.port_pllena = "PORT_UNUSED",
altpll_component.port_scanaclr = "PORT_UNUSED",
altpll_component.port_scanclk = "PORT_UNUSED",
altpll_component.port_scanclkena = "PORT_UNUSED",
altpll_component.port_scandata = "PORT_UNUSED",
altpll_component.port_scandataout = "PORT_UNUSED",
altpll_component.port_scandone = "PORT_UNUSED",
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
altpll_component.port_clk1 = "PORT_USED",
altpll_component.port_clk2 = "PORT_USED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
altpll_component.port_clk5 = "PORT_UNUSED",
altpll_component.port_clkena0 = "PORT_UNUSED",
altpll_component.port_clkena1 = "PORT_UNUSED",
altpll_component.port_clkena2 = "PORT_UNUSED",
altpll_component.port_clkena3 = "PORT_UNUSED",
altpll_component.port_clkena4 = "PORT_UNUSED",
altpll_component.port_clkena5 = "PORT_UNUSED",
altpll_component.port_extclk0 = "PORT_UNUSED",
altpll_component.port_extclk1 = "PORT_UNUSED",
altpll_component.port_extclk2 = "PORT_UNUSED",
altpll_component.port_extclk3 = "PORT_UNUSED",
altpll_component.self_reset_on_loss_lock = "ON",
altpll_component.width_clock = 5;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "1"
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "112.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "112.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "56.000000"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "1"
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "10000"
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "0"
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "50.000"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "112.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "112.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "56.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "-60.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "1"
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "27"
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "112"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27"
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "112"
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "-1488"
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "27"
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "56"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NO_COMPENSATION"
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "ON"
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf
// Retrieval info: CBX_MODULE_PREFIX: ON

View File

@@ -1,183 +0,0 @@
//
// scandoubler.v
//
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
// Copyright (c) 2017 Sorgelig
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// TODO: Delay vsync one line
module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
(
// system interface
input clk_sys,
input ce_pix,
input ce_pix_actual,
input hq2x,
// shifter video interface
input hs_in,
input vs_in,
input line_start,
input [DWIDTH:0] r_in,
input [DWIDTH:0] g_in,
input [DWIDTH:0] b_in,
input mono,
// output interface
output reg hs_out,
output vs_out,
output [DWIDTH:0] r_out,
output [DWIDTH:0] g_out,
output [DWIDTH:0] b_out
);
localparam DWIDTH = HALF_DEPTH ? 2 : 5;
assign vs_out = vs_in;
reg [2:0] phase;
reg [2:0] ce_div;
reg [7:0] pix_len = 0;
wire [7:0] pl = pix_len + 1'b1;
reg ce_x1, ce_x4;
reg req_line_reset;
wire ls_in = hs_in | line_start;
always @(negedge clk_sys) begin
reg old_ce;
reg [2:0] ce_cnt;
reg [7:0] pixsz2, pixsz4 = 0;
old_ce <= ce_pix;
if(~&pix_len) pix_len <= pix_len + 1'd1;
ce_x4 <= 0;
ce_x1 <= 0;
// use such odd comparison to place c_x4 evenly if master clock isn't multiple 4.
if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin
phase <= phase + 1'd1;
ce_x4 <= 1;
end
if(~old_ce & ce_pix) begin
pixsz2 <= {1'b0, pl[7:1]};
pixsz4 <= {2'b00, pl[7:2]};
ce_x1 <= 1;
ce_x4 <= 1;
pix_len <= 0;
phase <= phase + 1'd1;
ce_cnt <= ce_cnt + 1'd1;
if(ce_pix_actual) begin
phase <= 0;
ce_div <= ce_cnt + 1'd1;
ce_cnt <= 0;
req_line_reset <= 0;
end
if(ls_in) req_line_reset <= 1;
end
end
reg ce_sd;
always @(*) begin
case(ce_div)
2: ce_sd = !phase[0];
4: ce_sd = !phase[1:0];
default: ce_sd <= 1;
endcase
end
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
(
.clk(clk_sys),
.ce_x4(ce_x4 & ce_sd),
.inputpixel({b_in,g_in,r_in}),
.mono(mono),
.disable_hq2x(~hq2x),
.reset_frame(vs_in),
.reset_line(req_line_reset),
.read_y(sd_line),
.read_x(sd_h_actual),
.outpixel({b_out,g_out,r_out})
);
reg [10:0] sd_h_actual;
always @(*) begin
case(ce_div)
2: sd_h_actual = sd_h[10:1];
4: sd_h_actual = sd_h[10:2];
default: sd_h_actual = sd_h;
endcase
end
reg [10:0] sd_h;
reg [1:0] sd_line;
always @(posedge clk_sys) begin
reg [11:0] hs_max,hs_rise,hs_ls;
reg [10:0] hcnt;
reg [11:0] sd_hcnt;
reg hs, hs2, vs, ls;
if(ce_x1) begin
hs <= hs_in;
ls <= ls_in;
if(ls && !ls_in) hs_ls <= {hcnt,1'b1};
// falling edge of hsync indicates start of line
if(hs && !hs_in) begin
hs_max <= {hcnt,1'b1};
hcnt <= 0;
if(ls && !ls_in) hs_ls <= {10'd0,1'b1};
end else begin
hcnt <= hcnt + 1'd1;
end
// save position of rising edge
if(!hs && hs_in) hs_rise <= {hcnt,1'b1};
vs <= vs_in;
if(vs && ~vs_in) sd_line <= 0;
end
if(ce_x4) begin
hs2 <= hs_in;
// output counter synchronous to input and at twice the rate
sd_hcnt <= sd_hcnt + 1'd1;
sd_h <= sd_h + 1'd1;
if(hs2 && !hs_in) sd_hcnt <= hs_max;
if(sd_hcnt == hs_max) sd_hcnt <= 0;
// replicate horizontal sync at twice the speed
if(sd_hcnt == hs_max) hs_out <= 0;
if(sd_hcnt == hs_rise) hs_out <= 1;
if(sd_hcnt == hs_ls) sd_h <= 0;
if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1;
end
end
endmodule

View File

@@ -1,33 +0,0 @@
//
// PWM DAC
//
// MSBI is the highest bit number. NOT amount of bits!
//
module sigma_delta_dac #(parameter MSBI=7)
(
output reg DACout, //Average Output feeding analog lowpass
input [MSBI:0] DACin, //DAC input (excess 2**MSBI)
input CLK,
input RESET
);
reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder
reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder
reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder
reg [MSBI+2:0] DeltaB; //B input of Delta Adder
always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1);
always @(*) DeltaAdder = DACin + DeltaB;
always @(*) SigmaAdder = DeltaAdder + SigmaLatch;
always @(posedge CLK or posedge RESET) begin
if(RESET) begin
SigmaLatch <= 1'b1 << (MSBI+1);
DACout <= 1;
end else begin
SigmaLatch <= SigmaAdder;
DACout <= ~SigmaLatch[MSBI+2];
end
end
endmodule

View File

@@ -1,262 +0,0 @@
//
// sram.v
//
// Static RAM controller implementation using SDRAM MT48LC16M16A2
//
// Copyright (c) 2015,2016 Sorgelig
//
// Some parts of SDRAM code used from project:
// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ------------------------------------------
//
// v2.1 - Add universal 8/16 bit mode.
//
module sram
(
input init, // reset to initialize RAM
input clk, // clock ~100MHz
//
// SDRAM_* - signals to the MT48LC16M16 chip
inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus
output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus
output reg SDRAM_DQML, // two byte masks
output reg SDRAM_DQMH, //
output reg [1:0] SDRAM_BA, // two banks
output SDRAM_nCS, // a single chip select
output SDRAM_nWE, // write enable
output SDRAM_nRAS, // row address select
output SDRAM_nCAS, // columns address select
output SDRAM_CKE, // clock enable
//
input [1:0] wtbt, // 16bit mode: bit1 - write high byte, bit0 - write low byte,
// 8bit mode: 2'b00 - use addr[0] to decide which byte to write
// Ignored while reading.
//
input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations.
output [15:0] dout, // data output to cpu
input [15:0] din, // data input from cpu
input we, // cpu requests write
input rd, // cpu requests read
output reg ready // dout is valid. Ready to accept new read/write.
);
assign SDRAM_nCS = command[3];
assign SDRAM_nRAS = command[2];
assign SDRAM_nCAS = command[1];
assign SDRAM_nWE = command[0];
assign SDRAM_CKE = cke;
assign dout = latched ? data_l : data_d;
// no burst configured
localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
localparam MODE = {3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz
localparam cycles_per_refresh = 14'd780; // (64000*100)/8192-1 Calc'd as (64ms @ 100MHz)/8192 rose
localparam startup_refresh_max = 14'b11111111111111;
// SDRAM commands
localparam CMD_INHIBIT = 4'b1111;
localparam CMD_NOP = 4'b0111;
localparam CMD_ACTIVE = 4'b0011;
localparam CMD_READ = 4'b0101;
localparam CMD_WRITE = 4'b0100;
localparam CMD_BURST_TERMINATE = 4'b0110;
localparam CMD_PRECHARGE = 4'b0010;
localparam CMD_AUTO_REFRESH = 4'b0001;
localparam CMD_LOAD_MODE = 4'b0000;
reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles;
reg [3:0] command = CMD_INHIBIT;
reg cke = 0;
reg [24:0] save_addr;
reg latched;
reg [15:0] data;
wire[15:0] data_l = save_addr[0] ? {data[7:0], data[15:8]} : {data[15:8], data[7:0]};
wire[15:0] data_d = save_addr[0] ? {SDRAM_DQ[7:0], SDRAM_DQ[15:8]} : {SDRAM_DQ[15:8], SDRAM_DQ[7:0]};
typedef enum
{
STATE_STARTUP,
STATE_OPEN_1, STATE_OPEN_2,
STATE_WRITE,
STATE_READ,
STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3,
STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7
} state_t;
always @(posedge clk) begin
reg old_we, old_rd;
reg [CAS_LATENCY:0] data_ready_delay;
reg [15:0] new_data;
reg [1:0] new_wtbt;
reg new_we;
reg new_rd;
reg save_we = 1;
state_t state = STATE_STARTUP;
command <= CMD_NOP;
refresh_count <= refresh_count+1'b1;
data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]};
// make it ready 1T in advance
if(data_ready_delay[1]) {latched, ready} <= {1'b0, 1'b1};
if(data_ready_delay[0]) {latched, data} <= {1'b1, SDRAM_DQ};
case(state)
STATE_STARTUP: begin
//------------------------------------------------------------------------
//-- This is the initial startup state, where we wait for at least 100us
//-- before starting the start sequence
//--
//-- The initialisation is sequence is
//-- * de-assert SDRAM_CKE
//-- * 100us wait,
//-- * assert SDRAM_CKE
//-- * wait at least one cycle,
//-- * PRECHARGE
//-- * wait 2 cycles
//-- * REFRESH,
//-- * tREF wait
//-- * REFRESH,
//-- * tREF wait
//-- * LOAD_MODE_REG
//-- * 2 cycles wait
//------------------------------------------------------------------------
cke <= 1;
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
SDRAM_DQML <= 1;
SDRAM_DQMH <= 1;
SDRAM_A <= 0;
SDRAM_BA <= 0;
// All the commands during the startup are NOPS, except these
if(refresh_count == startup_refresh_max-31) begin
// ensure all rows are closed
command <= CMD_PRECHARGE;
SDRAM_A[10] <= 1; // all banks
SDRAM_BA <= 2'b00;
end else if (refresh_count == startup_refresh_max-23) begin
// these refreshes need to be at least tREF (66ns) apart
command <= CMD_AUTO_REFRESH;
end else if (refresh_count == startup_refresh_max-15)
command <= CMD_AUTO_REFRESH;
else if (refresh_count == startup_refresh_max-7) begin
// Now load the mode register
command <= CMD_LOAD_MODE;
SDRAM_A <= MODE;
end
//------------------------------------------------------
//-- if startup is complete then go into idle mode,
//-- get prepared to accept a new command, and schedule
//-- the first refresh cycle
//------------------------------------------------------
if(!refresh_count) begin
state <= STATE_IDLE;
ready <= 1;
refresh_count <= 0;
end
end
STATE_IDLE_7: state <= STATE_IDLE_6;
STATE_IDLE_6: state <= STATE_IDLE_5;
STATE_IDLE_5: state <= STATE_IDLE_4;
STATE_IDLE_4: state <= STATE_IDLE_3;
STATE_IDLE_3: state <= STATE_IDLE_2;
STATE_IDLE_2: state <= STATE_IDLE_1;
STATE_IDLE_1: begin
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
state <= STATE_IDLE;
// mask possible refresh to reduce colliding.
if(refresh_count > cycles_per_refresh) begin
//------------------------------------------------------------------------
//-- Start the refresh cycle.
//-- This tasks tRFC (66ns), so 6 idle cycles are needed @ 100MHz
//------------------------------------------------------------------------
state <= STATE_IDLE_7;
command <= CMD_AUTO_REFRESH;
refresh_count <= refresh_count - cycles_per_refresh + 1'd1;
end
end
STATE_IDLE: begin
// Priority is to issue a refresh if one is outstanding
if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1;
else if(new_rd | new_we) begin
new_we <= 0;
new_rd <= 0;
save_addr<= addr;
save_we <= new_we;
state <= STATE_OPEN_1;
command <= CMD_ACTIVE;
SDRAM_A <= addr[13:1];
SDRAM_BA <= addr[24:23];
end
end
// ACTIVE-to-READ or WRITE delay >20ns (-75)
STATE_OPEN_1: state <= STATE_OPEN_2;
STATE_OPEN_2: begin
SDRAM_A <= {4'b0010, save_addr[22:14]};
SDRAM_DQML <= save_we & (new_wtbt ? ~new_wtbt[0] : save_addr[0]);
SDRAM_DQMH <= save_we & (new_wtbt ? ~new_wtbt[1] : ~save_addr[0]);
state <= save_we ? STATE_WRITE : STATE_READ;
end
STATE_READ: begin
state <= STATE_IDLE_5;
command <= CMD_READ;
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
// Schedule reading the data values off the bus
data_ready_delay[CAS_LATENCY] <= 1;
end
STATE_WRITE: begin
state <= STATE_IDLE_5;
command <= CMD_WRITE;
SDRAM_DQ <= new_wtbt ? new_data : {new_data[7:0], new_data[7:0]};
ready <= 1;
end
endcase
if(init) begin
state <= STATE_STARTUP;
refresh_count <= startup_refresh_max - sdram_startup_cycles;
end
old_we <= we;
if(we & ~old_we) {ready, new_we, new_data, new_wtbt} <= {1'b0, 1'b1, din, wtbt};
old_rd <= rd;
if(rd & ~old_rd) begin
if(ready & ~save_we & (save_addr[24:1] == addr[24:1])) save_addr <= addr;
else {ready, new_rd} <= {1'b0, 1'b1};
end
end
endmodule

View File

@@ -1,131 +0,0 @@
//
// tape.v
//
// tape implementation for the PET2001 core for the MiST board
//
// Copyright (c) 2017 Sorgelig
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module tape
(
input reset,
input clk,
input ce_1m,
input ioctl_download,
input tape_pause,
output reg tape_audio,
output tape_active,
output reg tape_rd,
output reg [24:0] tape_addr,
input [7:0] tape_data
);
reg [23:0] cnt;
assign tape_active = (cnt>0);
always @(posedge clk) begin
reg [23:0] size;
//reg [7:0] version;
reg [23:0] tmp;
reg [26:0] bit_cnt, bit_half;
reg ioctl_downloadD;
reg [2:0] reload32;
reg byte_ready;
reg [7:0] din;
reg play_pause;
reg pauseD;
pauseD <= tape_pause;
if(tape_pause && ~pauseD) play_pause <= !play_pause;
if(reset || ioctl_download) begin
cnt <= 0;
reload32 <= 0;
byte_ready <= 0;
play_pause <= 0;
tape_rd <= 0;
size <= 0;
bit_cnt <= 0;
ioctl_downloadD <= ioctl_download;
end else if(ce_1m) begin
ioctl_downloadD <= ioctl_download;
tape_rd <= 0;
if(tape_rd) begin
byte_ready <= 1;
din <= tape_data;
end
// download complete, start parsing
if(!ioctl_download && ioctl_downloadD) begin
cnt <= 8;
tape_rd <= 1;
tape_addr <= 12;
end
if(cnt != 0) begin
if(byte_ready) begin
if(tape_addr<20) begin
cnt <= cnt - 1'd1;
tape_addr <= tape_addr + 1'd1;
byte_ready <= 0;
tape_rd <= 1;
case(tape_addr)
//12: version <= din;
16: size[7:0] <= din;
17: size[15:8] <= din;
18: size[23:16] <= din;
19: cnt <= size ? size : 24'd0;
default:;
endcase
end else begin
if(bit_cnt <= 1) begin
cnt <= cnt - 1'd1;
tape_addr <= tape_addr + 1'd1;
byte_ready <= 0;
tape_rd <= 1;
if(reload32 != 0) begin
tmp <= {din, tmp[23:8]};
reload32 <= reload32 - 1'd1;
if(reload32 == 1) begin
bit_cnt <= {din, tmp[23:8], 3'd0};
bit_half <= {din, tmp[23:8], 2'd0};
tape_audio <= 1;
end
end else if(din == 0) begin
reload32 <= 3;
end else begin
bit_cnt <= {din, 3'd0};
bit_half <= {din, 2'd0};
tape_audio <= 1;
end
end
end
end
if(!play_pause && (bit_cnt>1)) begin
bit_cnt <= bit_cnt - 1'd1;
if(bit_cnt < bit_half) tape_audio <= 0;
end
end
end
end
endmodule

View File

@@ -1,483 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////
//
// Engineer: Thomas Skibo
//
// Create Date: Sep 24, 2011
//
// Module Name: via6522
//
// Description:
//
// A simple implementation of the 6522 Versatile Interface Adapter (VIA).
// Tri-state lines aren't used. Instead, All PIA I/O signals have
// seperate "in" and "out" signals. Wire or ignore appropriately.
//
// A seperate "slow clock" (a synchronous pulse) runs the timers.
// Typically, it's 1Mhz.
//
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011, Thomas Skibo. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * The names of contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Thomas Skibo OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
module via6522
(
output reg [7:0] data_out, // cpu interface
input [7:0] data_in,
input [3:0] addr,
input strobe,
input we,
output reg irq,
output reg [7:0] porta_out,
input [7:0] porta_in,
output reg [7:0] portb_out,
input [7:0] portb_in,
input ca1_in,
output reg ca2_out,
input ca2_in,
output reg cb1_out,
input cb1_in,
output reg cb2_out,
input cb2_in,
input ce,
input clk,
input reset
);
// Register address offsets
parameter [3:0]
ADDR_PORTB = 4'h0,
ADDR_PORTA = 4'h1,
ADDR_DDRB = 4'h2,
ADDR_DDRA = 4'h3,
ADDR_TIMER1_LO = 4'h4,
ADDR_TIMER1_HI = 4'h5,
ADDR_TIMER1_LATCH_LO = 4'h6,
ADDR_TIMER1_LATCH_HI = 4'h7,
ADDR_TIMER2_LO = 4'h8,
ADDR_TIMER2_HI = 4'h9,
ADDR_SR = 4'ha,
ADDR_ACR = 4'hb,
ADDR_PCR = 4'hc,
ADDR_IFR = 4'hd,
ADDR_IER = 4'he,
ADDR_PORTA_NH = 4'hf;
wire wr_strobe = strobe && we;
wire rd_strobe = strobe && !we;
///////////////////////////////////////////////////
// IER - Interrupt Enable Register
reg [6:0] ier;
always @(posedge clk) begin
if (reset) ier <= 7'd0;
else if (wr_strobe && addr == ADDR_IER) ier <= data_in[7] ? (ier | data_in[6:0]) : (ier & ~data_in[6:0]);
end
////////////////////////////////////////////////////
// PCR - Peripheral Control Register
reg [7:0] pcr;
always @(posedge clk) begin
if (reset) pcr <= 8'h00;
else if (wr_strobe && addr == ADDR_PCR) pcr <= data_in;
end
//////////////////////////////////////////////////////
// ACR - Auxiliary Control Register
reg [7:0] acr;
always @(posedge clk) begin
if (reset) acr <= 8'h00;
else if (wr_strobe && addr == ADDR_ACR) acr <= data_in;
end
/////////////////////////////////////////////////////
// PORTs and DDRs
reg [7:0] ddra;
reg [7:0] ddrb;
reg pb7_nxt; // generated by timer1 logic, used when acr7 is set
// Implement PORTA (out)
always @(posedge clk) begin
if (reset) porta_out <= 8'h00;
else if (wr_strobe && (addr == ADDR_PORTA || addr == ADDR_PORTA_NH)) porta_out <= data_in;
end
// Implement DDRA
always @(posedge clk) begin
if (reset) ddra <= 8'h00;
else if (wr_strobe && addr == ADDR_DDRA) ddra <= data_in;
end
// Implement PORTB (out).
always @(posedge clk) begin
if (reset) portb_out[6:0] <= 7'h00;
else if (wr_strobe && addr == ADDR_PORTB) portb_out[6:0] <= data_in[6:0];
end
always @(posedge clk) begin
if (reset) portb_out[7] <= 1'b0;
else if (acr[7]) portb_out[7] <= pb7_nxt;
else if (wr_strobe && addr == ADDR_PORTB) portb_out[7] <= data_in[7];
end
// Implement DDRB
always @(posedge clk) begin
if (reset) ddrb <= 8'h00;
else if (wr_strobe && addr == ADDR_DDRB) ddrb <= data_in;
end
////////////////////////////////////////////////////////
// CA interrupt logic
reg irq_ca1;
reg irq_ca2;
// CA1 and CA2 transition logic.
reg ca1_in_1;
reg ca2_in_1;
always @(posedge clk) begin
ca1_in_1 <= ca1_in;
ca2_in_1 <= ca2_in;
end
// detect "active" transitions.
wire ca1_act_trans = ((ca1_in && !ca1_in_1 && pcr[0]) ||
(!ca1_in && ca1_in_1 && !pcr[0]));
wire ca2_act_trans = ((ca2_in && !ca2_in_1 && pcr[2]) ||
(!ca2_in && ca2_in_1 && !pcr[2]));
// logic for clearing CA1 and CA2 interrupt bits.
wire irq_ca1_clr = ((strobe && addr == ADDR_PORTA) ||
(wr_strobe && addr == ADDR_IFR && data_in[1]));
wire irq_ca2_clr = ((strobe && addr == ADDR_PORTA) ||
(wr_strobe && addr == ADDR_IFR && data_in[0]));
always @(posedge clk) begin
if (reset || (irq_ca1_clr && !ca1_act_trans)) irq_ca1 <= 1'b0;
else if (ca1_act_trans) irq_ca1 <= 1'b1;
end
always @(posedge clk) begin
if (reset || (irq_ca2_clr && !ca2_act_trans)) irq_ca2 <= 1'b0;
else if (ca2_act_trans) irq_ca2 <= 1'b1;
end
////////////////////////////////////////////////////////
// CB logic
reg irq_cb1;
reg irq_cb2;
// transition logic
reg cb1_in_1;
reg cb2_in_1;
always @(posedge clk) begin
cb1_in_1 <= cb1_in;
cb2_in_1 <= cb2_in;
end
// detect "active" transitions.
wire cb1_act_trans = ((cb1_in && !cb1_in_1 && pcr[4]) ||
(!cb1_in && cb1_in_1 && !pcr[4]));
wire cb2_act_trans = ((cb2_in && !cb2_in_1 && pcr[6]) ||
(!cb2_in && cb2_in_1 && !pcr[6]));
// logic for clearing CB1 and CB2 interrupt bits.
wire irq_cb1_clr = ((strobe && addr == ADDR_PORTB) ||
(wr_strobe && addr == ADDR_IFR && data_in[4]));
wire irq_cb2_clr = ((strobe && addr == ADDR_PORTB) ||
(wr_strobe && addr == ADDR_IFR && data_in[3]));
always @(posedge clk) begin
if (reset || (irq_cb1_clr && !cb1_act_trans)) irq_cb1 <= 1'b0;
else if (cb1_act_trans) irq_cb1 <= 1'b1;
end
always @(posedge clk) begin
if (reset || (irq_cb2_clr && !cb2_act_trans)) irq_cb2 <= 1'b0;
else if (cb2_act_trans) irq_cb2 <= 1'b1;
end
///////////////////////////////////////////////////
// CA2/CB2 output modes
always @(posedge clk) begin
case (pcr[3:1])
3'b100: ca2_out <= irq_ca1;
3'b101: ca2_out <= !ca1_act_trans;
3'b111: ca2_out <= 1'b1;
default: ca2_out <= 1'b0;
endcase
end
reg cb2_out_r;
wire portb_wr_strobe = wr_strobe && addr == ADDR_PORTB;
wire cb2_sr_out;
always @(posedge clk) begin
if (reset || (portb_wr_strobe && !cb1_act_trans)) cb2_out_r <= 1'b0;
else if (cb1_act_trans) cb2_out_r <= 1'b1;
end
always @(posedge clk) begin
if (acr[4]) cb2_out <= cb2_sr_out;
else begin
case (pcr[7:5])
3'b100: cb2_out <= cb2_out_r;
3'b101: cb2_out <= !portb_wr_strobe;
3'b111: cb2_out <= 1'b1;
default: cb2_out <= 1'b0;
endcase
end
end
//////////////////////////////////////////////////////////
// Implement PORTA (in) latch
reg [7:0] porta_in_r;
always @(posedge clk) begin
if (!acr[0] || !irq_ca1) porta_in_r <= porta_in;
end
// Implement PORTB (in) latch
reg [7:0] portb_in_r;
always @(posedge clk) begin
if (!acr[1] || !irq_cb1) portb_in_r <= portb_in;
end
///////////////////////////////////////////////////
// Timers
reg [15:0] timer1;
reg [7:0] timer1_latch_lo;
reg [7:0] timer1_latch_hi;
reg [15:0] timer2;
reg [7:0] timer2_latch_lo;
reg irq_t1_one_shot;
reg irq_t1;
reg irq_t2_one_shot;
reg irq_t2;
// TIMER1
always @(posedge clk) begin
if (reset) timer1 <= 16'hffff;
else if (wr_strobe && addr == ADDR_TIMER1_HI) timer1 <= {data_in, timer1_latch_lo};
else if (timer1 == 16'h0000 && ce && acr[6]) timer1 <= {timer1_latch_hi, timer1_latch_lo};
else if (ce) timer1 <= timer1 - 1'b1;
end
// T1 latch lo
always @(posedge clk) begin
if (reset) timer1_latch_lo <= 8'hff;
else if (wr_strobe && (addr == ADDR_TIMER1_LO || addr == ADDR_TIMER1_LATCH_LO)) timer1_latch_lo <= data_in;
end
// T1 latch hi
always @(posedge clk) begin
if (reset) timer1_latch_hi <= 8'hff;
else if (wr_strobe && (addr == ADDR_TIMER1_HI || addr == ADDR_TIMER1_LATCH_HI)) timer1_latch_hi <= data_in;
end
// "one-shot" logic so we only get an interrupt on first counter roll-over
always @(posedge clk) begin
if (reset) irq_t1_one_shot <= 1'b0;
else if (wr_strobe && addr == ADDR_TIMER1_HI) irq_t1_one_shot <= 1'b1;
else if (timer1 == 16'h0000 && ce) irq_t1_one_shot <= 1'b0;
end
// T1 interrupt set and clear logic
wire irq_t1_set = (timer1 == 16'h0000 && ce && (irq_t1_one_shot || acr[6]));
wire irq_t1_clr = ((wr_strobe && addr == ADDR_TIMER1_HI) ||
(wr_strobe && addr == ADDR_TIMER1_LATCH_HI) ||
(rd_strobe && addr == ADDR_TIMER1_LO) ||
(wr_strobe && addr == ADDR_IFR && data_in[6]));
// T1 IRQ
always @(posedge clk) begin
if (reset || irq_t1_clr) irq_t1 <= 1'b0;
else if (irq_t1_set) irq_t1 <= 1'b1;
end
// I forget what this is for
always @(posedge clk) begin
if (reset) pb7_nxt <= 1'b1;
else if (wr_strobe && addr == ADDR_TIMER1_HI) pb7_nxt <= 1'b0;
else if (timer1 == 16'h0001 && ce) pb7_nxt <= !pb7_nxt;
end
// TIMER2
always @(posedge clk) begin
if (reset) timer2 <= 16'hffff;
else if (wr_strobe && addr == ADDR_TIMER2_HI) timer2 <= {data_in, timer2_latch_lo};
else if ((!acr[5] || !portb_in[6]) && ce) timer2 <= timer2 - 1'b1;
end
// T2 latch lo (i.e. writes to T2L)
always @(posedge clk) begin
if (reset) timer2_latch_lo <= 8'hff;
else if (wr_strobe && addr == ADDR_TIMER2_LO) timer2_latch_lo <= data_in;
end
// T2 IRQ "one-shot" logic
always @(posedge clk) begin
if (reset) irq_t2_one_shot <= 1'b0;
else if (wr_strobe && addr == ADDR_TIMER2_HI) irq_t2_one_shot <= 1'b1;
else if (timer2 == 16'h0000 && ce) irq_t2_one_shot <= 1'b0;
end
// T2 IRQ set and clear logic
wire irq_t2_set = (timer2 == 16'h0000 && ce && irq_t2_one_shot);
wire irq_t2_clr = ((wr_strobe && addr == ADDR_TIMER2_HI) ||
(rd_strobe && addr == ADDR_TIMER2_LO) ||
(wr_strobe && addr == ADDR_IFR && data_in[5]));
// T2 IRQ
always @(posedge clk) begin
if (reset || irq_t2_clr) irq_t2 <= 1'b0;
else if (irq_t2_set) irq_t2 <= 1'b1;
end
////////////////////////////////////////////////////////
// SR - shift register
reg [7:0] sr;
reg [2:0] sr_cntr;
reg [7:0] sr_clk_div_ctr;
reg sr_clk_div;
reg irq_sr;
reg sr_go;
reg do_shift;
always @(posedge clk) begin
if (reset) sr <= 8'h00;
else if (wr_strobe && addr == ADDR_SR) sr <= data_in;
else if (do_shift) sr <= { sr[6:0], (acr[4] ? sr[7] : cb2_in) };
end
assign cb2_sr_out = sr[7];
always @(posedge clk) begin
if (reset) sr_clk_div_ctr <= 8'd0;
else if (ce && sr_clk_div_ctr == 8'd0) sr_clk_div_ctr <= timer2_latch_lo;
else if (ce) sr_clk_div_ctr <= sr_clk_div_ctr - 1'b1;
end
always @(posedge clk) begin
if (reset) sr_clk_div <= 1'b0;
else sr_clk_div <= (ce && sr_clk_div_ctr == 8'd0);
end
always @(posedge clk) begin
if (reset || (strobe && addr == ADDR_SR)) sr_cntr <= 3'd7;
else if (do_shift) sr_cntr <= sr_cntr - 1'b1;
end
// SR IRQ set and clr logic
wire irq_sr_set = do_shift && sr_cntr == 3'b000;
wire irq_sr_clr = ((strobe && addr == ADDR_SR) || (wr_strobe && addr == ADDR_IFR && data_in[2]));
// SR IRQ
always @(posedge clk) begin
if (reset || (irq_sr_clr && !irq_sr_set)) irq_sr <= 1'b0;
else if (irq_sr_set) irq_sr <= 1'b1;
end
always @(posedge clk) begin
if (reset) sr_go <= 1'b0;
else if (strobe && addr == ADDR_SR) sr_go <= 1'b1;
else if (irq_sr_set) sr_go <= 1'b0;
end
// cominatorial logic for do_shift signal.
always @(sr_clk_div or ce or cb1_act_trans or sr_go or acr) begin
case (acr[4:2])
3'b000: do_shift = 1'b0;
3'b100: do_shift = sr_clk_div;
3'b001,
3'b101: do_shift = (sr_go && sr_clk_div);
3'b010,
3'b110: do_shift = (sr_go && ce);
3'b011,
3'b111: do_shift = cb1_act_trans;
endcase
end
always @(posedge clk) begin
if (reset) cb1_out <= 1'b1;
else if (do_shift) cb1_out <= !cb1_out;
end
////////////////////////////////////////////////////////
// IRQ and enable logic.
//
// IFR register (not including bit 7)
wire [6:0] ifr = { irq_t1, irq_t2, irq_cb1, irq_cb2, irq_sr, irq_ca1, irq_ca2 };
// IRQ combinatorial logic
wire irq_p = |{ (ifr & ier) };
// IRQ output
always @(posedge clk) begin
if (reset) irq <= 1'b0;
else irq <= irq_p;
end
///////////////////////////////////////////////////
// Read data mux
wire [7:0] porta = (porta_out & ddra) | (porta_in_r & ~ddra);
wire [7:0] portb = (portb_out & ddrb) | (portb_in_r & ~ddrb);
always @(*) begin
case (addr)
ADDR_PORTB: data_out = portb;
ADDR_PORTA: data_out = porta;
ADDR_DDRB: data_out = ddrb;
ADDR_DDRA: data_out = ddra;
ADDR_TIMER1_LO: data_out = timer1[7:0];
ADDR_TIMER1_HI: data_out = timer1[15:8];
ADDR_TIMER1_LATCH_LO: data_out = timer1_latch_lo;
ADDR_TIMER1_LATCH_HI: data_out = timer1_latch_hi;
ADDR_TIMER2_LO: data_out = timer2[7:0];
ADDR_TIMER2_HI: data_out = timer2[15:8];
ADDR_IER: data_out = {1'b1, ier};
ADDR_PCR: data_out = pcr;
ADDR_ACR: data_out = acr;
ADDR_IFR: data_out = {irq_p, ifr};
ADDR_SR: data_out = sr;
ADDR_PORTA_NH: data_out = porta;
default: data_out = 8'hXX;
endcase
end
endmodule // via6522

View File

@@ -1,242 +0,0 @@
//
//
// Copyright (c) 2017 Sorgelig
//
// This program is GPL Licensed. See COPYING for the full license.
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
//
// LINE_LENGTH: Length of display line in pixels
// Usually it's length from HSync to HSync.
// May be less if line_start is used.
//
// HALF_DEPTH: If =1 then color dept is 3 bits per component
// For half depth 6 bits monochrome is available with
// mono signal enabled and color = {G, R}
module video_mixer
#(
parameter LINE_LENGTH = 768,
parameter HALF_DEPTH = 0,
parameter OSD_COLOR = 3'd4,
parameter OSD_X_OFFSET = 10'd0,
parameter OSD_Y_OFFSET = 10'd0
)
(
// master clock
// it should be multiple by (ce_pix*4).
input clk_sys,
// Pixel clock or clock_enable (both are accepted).
input ce_pix,
// Some systems have multiple resolutions.
// ce_pix_actual should match ce_pix where every second or fourth pulse is enabled,
// thus half or qurter resolutions can be used without brake video sync while switching resolutions.
// For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix.
input ce_pix_actual,
// OSD SPI interface
input SPI_SCK,
input SPI_SS3,
input SPI_DI,
// scanlines (00-none 01-25% 10-50% 11-75%)
input [1:0] scanlines,
// 0 = HVSync 31KHz, 1 = CSync 15KHz
input scandoubler_disable,
// High quality 2x scaling
input hq2x,
// YPbPr always uses composite sync
input ypbpr,
// 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space)
input ypbpr_full,
// color
input [DWIDTH:0] R,
input [DWIDTH:0] G,
input [DWIDTH:0] B,
// Monochrome mode (for HALF_DEPTH only)
input mono,
// interlace sync. Positive pulses.
input HSync,
input VSync,
// Falling of this signal means start of informative part of line.
// It can be horizontal blank signal.
// This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler
// If FPGA RAM is not an issue, then simply set it to 0 for whole line processing.
// Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts.
// Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel
// before first informative pixel.
input line_start,
// MiST video output signals
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
output VGA_VS,
output VGA_HS
);
localparam DWIDTH = HALF_DEPTH ? 2 : 5;
wire [DWIDTH:0] R_sd;
wire [DWIDTH:0] G_sd;
wire [DWIDTH:0] B_sd;
wire hs_sd, vs_sd;
scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) scandoubler
(
.*,
.hs_in(HSync),
.vs_in(VSync),
.r_in(R),
.g_in(G),
.b_in(B),
.hs_out(hs_sd),
.vs_out(vs_sd),
.r_out(R_sd),
.g_out(G_sd),
.b_out(B_sd)
);
wire [DWIDTH:0] rt = (scandoubler_disable ? R : R_sd);
wire [DWIDTH:0] gt = (scandoubler_disable ? G : G_sd);
wire [DWIDTH:0] bt = (scandoubler_disable ? B : B_sd);
generate
if(HALF_DEPTH) begin
wire [5:0] r = mono ? {gt,rt} : {rt,rt};
wire [5:0] g = mono ? {gt,rt} : {gt,gt};
wire [5:0] b = mono ? {gt,rt} : {bt,bt};
end else begin
wire [5:0] r = rt;
wire [5:0] g = gt;
wire [5:0] b = bt;
end
endgenerate
wire hs = (scandoubler_disable ? HSync : hs_sd);
wire vs = (scandoubler_disable ? VSync : vs_sd);
reg scanline = 0;
always @(posedge clk_sys) begin
reg old_hs, old_vs;
old_hs <= hs;
old_vs <= vs;
if(old_hs && ~hs) scanline <= ~scanline;
if(old_vs && ~vs) scanline <= 0;
end
wire [5:0] r_out, g_out, b_out;
always @(*) begin
case(scanlines & {scanline, scanline})
1: begin // reduce 25% = 1/2 + 1/4
r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]};
g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]};
b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]};
end
2: begin // reduce 50% = 1/2
r_out = {1'b0, r[5:1]};
g_out = {1'b0, g[5:1]};
b_out = {1'b0, b[5:1]};
end
3: begin // reduce 75% = 1/4
r_out = {2'b00, r[5:2]};
g_out = {2'b00, g[5:2]};
b_out = {2'b00, b[5:2]};
end
default: begin
r_out = r;
g_out = g;
b_out = b;
end
endcase
end
wire [5:0] red, green, blue;
osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
(
.*,
.R_in(r_out),
.G_in(g_out),
.B_in(b_out),
.HSync(hs),
.VSync(vs),
.R_out(red),
.G_out(green),
.B_out(blue)
);
wire [5:0] yuv_full[225] = '{
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
6'd63
};
// http://marsee101.blog19.fc2.com/blog-entry-2311.html
// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B)
// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red;
assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green;
assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue;
assign VGA_VS = (scandoubler_disable | ypbpr) ? 1'b1 : ~vs_sd;
assign VGA_HS = scandoubler_disable ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd;
endmodule