OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /thor/trunk/FT64
    from Rev 45 to Rev 46
    Reverse comparison

Rev 45 → Rev 46

/rtl/bench/FT64SoC_tb2.v
0,0 → 1,34
 
module FT64SoC_tb2();
reg rst;
reg clk;
reg irq;
wire [7:0] led;
 
initial begin
rst = 0;
clk = 0;
irq = 0;
#10 rst = 1;
#50 rst = 0;
#6000 irq = 1;
#2000 irq = 0;
end
 
always #5 clk = ~clk;
//always #4000 irq = ~irq;
 
FT64SoC usoc1 (
.cpu_resetn(~rst),
.xclk(clk),
.led(led),
.sw(8'h00),
.irq(irq),
.TMDS_OUT_clk_p(),
.TMDS_OUT_clk_n(),
.TMDS_OUT_data_p(),
.TMDS_OUT_data_n()
);
 
 
endmodule
/rtl/bench/soc/NexysVideoClkgen/NexysVideoClkgen.veo
0,0 → 1,88
 
//
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
//
//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// None
//
//----------------------------------------------------------------------------
// Output Output Phase Duty Cycle Pk-to-Pk Phase
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
//----------------------------------------------------------------------------
// __clk100___100.000______0.000______50.0______144.719____114.212
// __clk400___400.000______0.000______50.0______111.164____114.212
// ___clk80____80.000______0.000______50.0______151.652____114.212
// ___clk50____25.000______0.000______50.0______191.696____114.212
// __clk200___100.000______0.000______50.0______144.719____114.212
//
//----------------------------------------------------------------------------
// Input Clock Freq (MHz) Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________100.000____________0.010
 
// The following must be inserted into your Verilog file for this
// core to be instantiated. Change the instance name and port connections
// (in parentheses) to your own signal names.
 
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
 
NexysVideoClkgen instance_name
(
// Clock out ports
.clk100(clk100), // output clk100
.clk400(clk400), // output clk400
.clk80(clk80), // output clk80
.clk50(clk50), // output clk50
.clk200(clk200), // output clk200
// Status and control signals
.reset(reset), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(clk_in1)); // input clk_in1
// INST_TAG_END ------ End INSTANTIATION Template ---------
/rtl/bench/soc/NexysVideoClkgen/NexysVideoClkgen_stub.v
0,0 → 1,27
// Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
// --------------------------------------------------------------------------------
// Tool Version: Vivado v.2017.3 (win64) Build 2018833 Wed Oct 4 19:58:22 MDT 2017
// Date : Fri Jan 26 22:39:31 2018
// Host : Ateana3 running 64-bit major release (build 9200)
// Command : write_verilog -force -mode synth_stub
// C:/Cores5/FT64/FT64/FT64.srcs/sources_1/ip/NexysVideoClkgen/NexysVideoClkgen_stub.v
// Design : NexysVideoClkgen
// Purpose : Stub declaration of top-level module interface
// Device : xc7a200tsbg484-1
// --------------------------------------------------------------------------------
 
// This empty module with port declaration file causes synthesis tools to infer a black box for IP.
// The synthesis directives are for Synopsys Synplify support to prevent IO buffer insertion.
// Please paste the declaration into a Verilog source file or add the file as an additional source.
module NexysVideoClkgen(clk100, clk400, clk80, clk50, clk200, reset, locked,
clk_in1)
/* synthesis syn_black_box black_box_pad_pin="clk100,clk400,clk80,clk50,clk200,reset,locked,clk_in1" */;
output clk100;
output clk400;
output clk80;
output clk50;
output clk200;
input reset;
output locked;
input clk_in1;
endmodule
/rtl/bench/soc/NexysVideoClkgen/NexysVideoClkgen_stub.vhdl
0,0 → 1,35
-- Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
-- --------------------------------------------------------------------------------
-- Tool Version: Vivado v.2017.3 (win64) Build 2018833 Wed Oct 4 19:58:22 MDT 2017
-- Date : Fri Jan 26 22:39:31 2018
-- Host : Ateana3 running 64-bit major release (build 9200)
-- Command : write_vhdl -force -mode synth_stub
-- C:/Cores5/FT64/FT64/FT64.srcs/sources_1/ip/NexysVideoClkgen/NexysVideoClkgen_stub.vhdl
-- Design : NexysVideoClkgen
-- Purpose : Stub declaration of top-level module interface
-- Device : xc7a200tsbg484-1
-- --------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
entity NexysVideoClkgen is
Port (
clk100 : out STD_LOGIC;
clk400 : out STD_LOGIC;
clk80 : out STD_LOGIC;
clk50 : out STD_LOGIC;
clk200 : out STD_LOGIC;
reset : in STD_LOGIC;
locked : out STD_LOGIC;
clk_in1 : in STD_LOGIC
);
 
end NexysVideoClkgen;
 
architecture stub of NexysVideoClkgen is
attribute syn_black_box : boolean;
attribute black_box_pad_pin : string;
attribute syn_black_box of stub : architecture is true;
attribute black_box_pad_pin of stub : architecture is "clk100,clk400,clk80,clk50,clk200,reset,locked,clk_in1";
begin
end;
/rtl/bench/soc/bootrom.v
0,0 → 1,86
// ============================================================================
// __
// \\__/ o\ (C) 2012-2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 bootrom(rst_i, clk_i, cti_i, cs_i, cyc_i, stb_i, ack_o, adr_i, dat_o);
parameter WID=64;
//parameter FNAME = "c:\\cores5\\FT64\\trunk\\software\\boot\\boot.ve0";
input rst_i;
input clk_i;
input [2:0] cti_i;
input cs_i;
input cyc_i;
input stb_i;
output ack_o;
input [17:0] adr_i;
output [WID-1:0] dat_o;
reg [WID-1:0] dat_o;
 
integer n;
 
reg [WID-1:0] rommem [32767:0];
reg [14:0] radr;
reg [2:0] cnt;
 
initial begin
`include "c:\\cores5\\FT64\\trunk\\software\\boot\\boottc.ve0";
end
 
wire cs = cs_i && cyc_i && stb_i;
 
reg rdy,rdy1,rdy2;
always @(posedge clk_i)
begin
rdy1 <= cs;
rdy <= rdy1 & cs & cnt!=3'b100;
end
assign ack_o = cs ? rdy : 1'b0;
 
 
wire pe_cs;
edge_det u1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs), .pe(pe_cs), .ne(), .ee() );
 
reg [14:0] ctr;
always @(posedge clk_i)
if (pe_cs) begin
if (cti_i==3'b000)
ctr[1:0] <= adr_i[4:3];
else
ctr[1:0] <= adr_i[4:3] + 2'd1;
ctr[14:2] <= adr_i[17:5];
cnt <= 3'b00;
end
else if (cs && cnt!=3'b11 && cti_i != 3'b000) begin
ctr[1:0] <= ctr[1:0] + 2'd1;
cnt <= cnt + 3'd1;
end
 
always @(posedge clk_i)
radr <= pe_cs ? adr_i[17:3] : ctr;
 
//assign dat_o = cs ? {smemH[radr],smemG[radr],smemF[radr],smemE[radr],
// smemD[radr],smemC[radr],smemB[radr],smemA[radr]} : 64'd0;
 
always @(posedge clk_i)
dat_o <= rommem[radr];
 
endmodule
/rtl/bench/soc/keyboard/Ps2Keyboard.v
0,0 → 1,96
`timescale 1ns / 1ps
// ============================================================================
// Ps2Keyboard.v - PS2 compatible keyboard interface
//
// 2015 Robert Finch
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// Reg
// 0 keyboard transmit/receive register
// 1 status reg. itk xxxx p
// i = interrupt status
// t = transmit complete
// k = transmit acknowledge receipt (from keyboard)
// p = parity error
// A write to the status register clears the transmitter
// state
//
// ============================================================================
//
module Ps2Keyboard(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o, kclk, kd, irq_o);
parameter pAckStyle = 1'b0;
input rst_i;
input clk_i;
input cs_i;
input cyc_i;
input stb_i;
output ack_o;
input we_i;
input [3:0] adr_i;
input [7:0] dat_i;
output reg [7:0] dat_o;
inout tri kclk;
inout tri kd;
output irq_o;
 
reg rd;
reg [3:0] cd;
wire busy;
wire err;
wire read_data;
wire write_data;
wire [7:0] rx_data;
assign ack_o = cs_i & cyc_i & stb_i;
assign irq_o = rd;
 
Ps2Interface u1
(
.clk(clk_i),
.rst(rst_i),
.ps2_clk(kclk),
.ps2_data(kd),
.tx_data(dat_i),
.write_data(write_data),
.rx_data(rx_data),
.read_data(read_data),
.busy(busy),
.err(err)
);
 
always @(posedge clk_i)
if (rst_i) begin
rd <= 1'b0;
end
else begin
cd <= {cd[2:0],1'b0};
if (read_data)
rd <= 1'b1;
else if (ack_o & ~we_i)
cd[0] <= 1'b1;
if (cd[3])
rd <= 1'b0;
end
 
always @*
if (adr_i[0])
dat_o <= {rd,busy,5'b0,err};
else
dat_o <= rx_data;
 
assign write_data = ack_o & we_i & ~adr_i[0];
 
endmodule
/rtl/bench/soc/keyboard/Ps2Keyboard_sim.v
0,0 → 1,116
`timescale 1ns / 1ps
// ============================================================================
// Ps2Keyboard.v - PS2 compatible keyboard interface
//
// 2015 Robert Finch
// robfinch<remove>@finitron.ca
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// Reg
// 0 keyboard transmit/receive register
// 1 status reg. itk xxxx p
// i = interrupt status
// t = transmit complete
// k = transmit acknowledge receipt (from keyboard)
// p = parity error
// A write to the status register clears the transmitter
// state
//
// ============================================================================
//
module Ps2Keyboard_sim(rst_i, clk_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o, kclk, kd, irq_o);
parameter pIOAddress = 32'hFFDC0000;
parameter pAckStyle = 1'b0;
input rst_i;
input clk_i;
input cyc_i;
input stb_i;
output ack_o;
input we_i;
input [31:0] adr_i;
input [7:0] dat_i;
output reg [7:0] dat_o;
inout tri kclk;
inout tri kd;
output irq_o;
 
reg rd;
wire write_data;
wire cs_kbd = cyc_i & stb_i && adr_i[31:4]==pIOAddress[31:4];
assign ack_o = cs_kbd;
assign irq_o = rd;
reg read_data;
reg busy;
reg err;
reg [7:0] rx_data;
reg [19:0] cnt;
always @(posedge clk_i)
if (rst_i)
cnt <= 20'd0;
else
cnt <= cnt + 1;
 
always @(posedge clk_i)
if (rst_i) begin
read_data <= 1'b0;
rx_data <= 8'h00;
busy <= 1'b0;
err <= 1'b0;
end
else begin
read_data <= 0;
case(cnt)
300:
begin
read_data <= 1'b1;
rx_data <= 8'h41;
end
350:
begin
read_data <= 1'b1;
rx_data <= 8'h42;
end
400:
begin
read_data <= 1'b1;
rx_data <= 8'h43;
end
endcase
end
 
always @(posedge clk_i)
if (rst_i)
rd <= 1'b0;
else begin
if (read_data)
rd <= 1'b1;
else if (cs_kbd & ~we_i)
rd <= 1'b0;
end
 
always @*
if (cs_kbd & ~we_i) begin
if (adr_i[0])
dat_o <= {rd,busy,5'b0,err};
else
dat_o <= rx_data;
end
else
dat_o <= 8'h00;
 
assign write_data = cs_kbd & we_i & ~adr_i[0];
 
endmodule
/rtl/bench/soc/random.v
0,0 → 1,188
// ============================================================================
// __
// \\__/ o\ (C) 2011-2017 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// random.v
// Multi-stream random number generator.
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// Reg no.
// 0 read: random output bits [31:0], write: gen next number
// 1 random stream number
// 2 m_z seed setting bits [31:0]
// 3 m_w seed setting bits [31:0]
//
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |WISHBONE Datasheet
// |WISHBONE SoC Architecture Specification, Revision B.3
// |
// |Description: Specifications:
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |General Description: random number generator
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |Supported Cycles: SLAVE,READ/WRITE
// | SLAVE,BLOCK READ/WRITE
// | SLAVE,RMW
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |Data port, size: 16 bit
// |Data port, granularity: 16 bit
// |Data port, maximum operand size: 16 bit
// |Data transfer ordering: Undefined
// |Data transfer sequencing: Undefined
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |Clock frequency constraints: none
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |Supported signal list and Signal Name WISHBONE equiv.
// |cross reference to equivalent ack_o ACK_O
// |WISHBONE signals adr_i[43:0] ADR_I()
// | clk_i CLK_I
// | rst_i RST_I()
// | dat_i(15:0) DAT_I()
// | dat_o(15:0) DAT_O()
// | cyc_i CYC_I
// | stb_i STB_I
// | we_i WE_I
// |
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// |Special requirements:
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// ============================================================================
//
// Uses George Marsaglia's multiply method
//
// m_w = <choose-initializer>; /* must not be zero */
// m_z = <choose-initializer>; /* must not be zero */
//
// uint get_random()
// {
// m_z = 36969 * (m_z & 65535) + (m_z >> 16);
// m_w = 18000 * (m_w & 65535) + (m_w >> 16);
// return (m_z << 16) + m_w; /* 32-bit result */
// }
//
`define TRUE 1'b1
`define FALSE 1'b0
 
module random(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o);
input rst_i;
input clk_i;
input cs_i;
input cyc_i;
input stb_i;
output reg ack_o;
input we_i;
input [3:0] adr_i;
input [31:0] dat_i;
output reg [31:0] dat_o;
parameter pAckStyle = 1'b0;
 
reg ack;
wire cs = cs_i && cyc_i && stb_i;
always @(posedge clk_i)
ack_o <= cs;
//always @*
// ack_o <= cs ? ack : pAckStyle;
 
reg [9:0] stream;
reg [31:0] next_m_z;
reg [31:0] next_m_w;
reg [31:0] out;
reg wrw, wrz;
reg [31:0] w,z;
wire [31:0] m_zs;
wire [31:0] m_ws;
 
rand_ram u1 (clk_i, wrw, stream, w, m_ws);
rand_ram u2 (clk_i, wrz, stream, z, m_zs);
 
always @*
begin
next_m_z <= (18'h36969 * m_zs[15:0]) + m_zs[31:16];
next_m_w <= (18'h18000 * m_ws[15:0]) + m_ws[31:16];
end
 
// Register read path
//
always @(posedge clk_i)
case(adr_i[3:2])
2'd0: dat_o <= {m_zs[15:0],16'd0} + m_ws;
2'd1: dat_o <= {6'h0,stream};
// Uncomment these for register read-back
// 3'd4: dat_o <= m_z[31:16];
// 3'd5: dat_o <= m_z[15: 0];
// 3'd6: dat_o <= m_w[31:16];
// 3'd7: dat_o <= m_w[15: 0];
default: dat_o <= 32'h0000;
endcase
 
// Register write path
//
always @(posedge clk_i)
begin
wrw <= `FALSE;
wrz <= `FALSE;
if (cs) begin
if (we_i)
case(adr_i[3:2])
2'd0:
begin
z <= next_m_z;
w <= next_m_w;
wrw <= `TRUE;
wrz <= `TRUE;
end
2'd1: stream <= dat_i[9:0];
2'd2: begin z <= dat_i; wrz <= `TRUE; end
2'd3: begin w <= dat_i; wrw <= `TRUE; end
endcase
end
end
 
endmodule
 
 
// Tools were inferring a massive distributed ram so we help them out a bit by
// creating an explicit ram definition.
 
module rand_ram(clk, wr, ad, i, o);
input clk;
input wr;
input [9:0] ad;
input [31:0] i;
output [31:0] o;
 
reg [31:0] ri;
reg [9:0] regadr;
reg regwr;
(* RAM_STYLE="BLOCK" *)
reg [31:0] mem [0:1023];
 
always @(posedge clk)
regadr <= ad;
always @(posedge clk)
regwr <= wr;
always @(posedge clk)
ri <= i;
always @(posedge clk)
if (regwr)
mem[regadr] <= ri;
assign o = mem[regadr];
 
endmodule
/rtl/bench/soc/scratchmem.v
0,0 → 1,141
// ============================================================================
// __
// \\__/ o\ (C) 2012-2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 scratchmem(rst_i, clk_i, cti_i, cs_i, cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o);
input rst_i;
input clk_i;
input [2:0] cti_i;
input cs_i;
input cyc_i;
input stb_i;
output ack_o;
input we_i;
input [7:0] sel_i;
input [14:0] adr_i;
input [63:0] dat_i;
output [63:0] dat_o;
reg [63:0] dat_o;
 
integer n;
 
reg [7:0] smemA [4095:0];
reg [7:0] smemB [4095:0];
reg [7:0] smemC [4095:0];
reg [7:0] smemD [4095:0];
reg [7:0] smemE [4095:0];
reg [7:0] smemF [4095:0];
reg [7:0] smemG [4095:0];
reg [7:0] smemH [4095:0];
reg [14:2] radr;
 
 
initial begin
for (n = 0; n < 4096; n = n + 1)
begin
smemA[n] = 0;
smemB[n] = 0;
smemC[n] = 0;
smemD[n] = 0;
smemE[n] = 0;
smemF[n] = 0;
smemG[n] = 0;
smemH[n] = 0;
end
end
 
wire cs = cs_i && cyc_i && stb_i;
 
reg [2:0] cnt;
reg rdy,rdy1;
always @(posedge clk_i)
begin
rdy1 <= cs;
rdy <= rdy1 & cs && cnt!=3'b100;
end
assign ack_o = cs ? (we_i ? 1'b1 : rdy) : 1'b0;
 
 
always @(posedge clk_i)
if (cs & we_i) begin
$display ("wrote to scratchmem: %h=%h:%h", adr_i, dat_i, sel_i);
if (adr_i==15'h1ff50 && dat_i==64'h20) begin
$display("1f50=20");
$finish;
end
end
always @(posedge clk_i)
if (cs & we_i & sel_i[0])
smemA[adr_i[14:3]] <= dat_i[7:0];
always @(posedge clk_i)
if (cs & we_i & sel_i[1])
smemB[adr_i[14:3]] <= dat_i[15:8];
always @(posedge clk_i)
if (cs & we_i & sel_i[2])
smemC[adr_i[14:3]] <= dat_i[23:16];
always @(posedge clk_i)
if (cs & we_i & sel_i[3])
smemD[adr_i[14:3]] <= dat_i[31:24];
always @(posedge clk_i)
if (cs & we_i & sel_i[4])
smemE[adr_i[14:3]] <= dat_i[39:32];
always @(posedge clk_i)
if (cs & we_i & sel_i[5])
smemF[adr_i[14:3]] <= dat_i[47:40];
always @(posedge clk_i)
if (cs & we_i & sel_i[6])
smemG[adr_i[14:3]] <= dat_i[55:48];
always @(posedge clk_i)
if (cs & we_i & sel_i[7])
smemH[adr_i[14:3]] <= dat_i[63:56];
 
wire pe_cs;
edge_det u1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs), .pe(pe_cs), .ne(), .ee() );
 
reg [12:0] ctr;
always @(posedge clk_i)
if (pe_cs) begin
if (cti_i==3'b000)
ctr <= adr_i[14:3];
else
ctr <= adr_i[14:3] + 12'd1;
cnt <= 3'b000;
end
else if (cs && cnt[2:0]!=3'b011 && cti_i!=3'b000) begin
ctr[1:0] <= ctr[1:0] + 2'd1;
cnt <= cnt + 3'd1;
end
 
always @(posedge clk_i)
radr <= pe_cs ? adr_i[14:3] : ctr;
 
//assign dat_o = cs ? {smemH[radr],smemG[radr],smemF[radr],smemE[radr],
// smemD[radr],smemC[radr],smemB[radr],smemA[radr]} : 64'd0;
 
always @(posedge clk_i)
begin
dat_o <= {smemH[radr],smemG[radr],smemF[radr],smemE[radr],smemD[radr],smemC[radr],smemB[radr],smemA[radr]};
if (!we_i)
$display("read from scratchmem: %h=%h", radr, {smemB[radr],smemA[radr]});
end
 
endmodule
/rtl/bench/soc/video/FT64_TextController.v
0,0 → 1,669
// ============================================================================
// __
// \\__/ o\ (C) 2006-2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// FT64_TextController.v
// text controller
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
//
// Text Controller
//
// FEATURES
//
// This core requires an external timing generator to provide horizontal
// and vertical sync signals, but otherwise can be used as a display
// controller on it's own. However, this core may also be embedded within
// another core such as a VGA controller.
//
// Window positions are referenced to the rising edge of the vertical and
// horizontal sync pulses.
//
// The core includes an embedded dual port RAM to hold the screen
// characters.
//
//
//--------------------------------------------------------------------
// Registers
//
// 00h - nnnnnnnn number of columns (horizontal displayed number of characters)
// 04h - nnnnnnnn number of rows (vertical displayed number of characters)
// 08h - n nnnnnnnn window left (horizontal sync position - reference for left edge of displayed)
// 0Ch - n nnnnnnnn window top (vertical sync position - reference for the top edge of displayed)
// 10h - ---nnnnn maximum scan line (char ROM max value is 7)
// 14h - hhhhwwww pixel size, hhhh=height,wwww=width
// 18h - - -------r reset state bit
// 1Ch - n nnnnnnnn color code for transparent background
// 20h - -BPnnnnn cursor start / blink control
// BP: 00=no blink
// BP: 01=no display
// BP: 10=1/16 field rate blink
// BP: 11=1/32 field rate blink
// 24h - ----nnnnn cursor end
// 28h - aaaaaaaa aaaaaaaaa start address (index into display memory)
// 2Ch - aaaaaaaa aaaaaaaaa cursor position
// 30h - aaaaaaaa aaaaaaaaa light pen position
//--------------------------------------------------------------------
//
// ============================================================================
 
module FT64_TextController(
rst_i, clk_i, cs_i,
cyc_i, stb_i, ack_o, wr_i, adr_i, dat_i, dat_o,
lp, curpos,
vclk, hsync, vsync, blank, border, rgbIn, rgbOut
);
parameter num = 4'd1;
parameter COLS = 12'd80;
parameter ROWS = 12'd31;
 
// Syscon
input rst_i; // reset
input clk_i; // clock
 
// Slave signals
input cs_i; // circuit select
input cyc_i; // valid bus cycle
input stb_i; // data strobe
output ack_o; // data acknowledge
input wr_i; // write
input [15:0] adr_i; // address
input [31:0] dat_i; // data input
output [31:0] dat_o; // data output
reg [31:0] dat_o;
 
//
input lp; // light pen
input [15:0] curpos; // cursor position
 
// Video signals
input vclk; // video dot clock
input hsync; // end of scan line
input vsync; // end of frame
input blank; // blanking signal
input border; // border area
input [24:0] rgbIn; // input pixel stream
output reg [24:0] rgbOut; // output pixel stream
 
 
reg [23:0] bkColor24; // background color
reg [23:0] fgColor24; // foreground color
wire [23:0] tcColor24; // transparent color
 
wire pix; // pixel value from character generator 1=on,0=off
 
reg por;
reg [15:0] rego;
reg [11:0] windowTop;
reg [11:0] windowLeft;
reg [11:0] numCols;
reg [11:0] numRows;
reg [11:0] charOutDelay;
reg [ 1:0] mode;
reg [ 4:0] maxScanline;
reg [ 4:0] maxScanpix;
reg [ 4:0] cursorStart, cursorEnd;
reg [15:0] cursorPos;
reg [1:0] cursorType;
reg [15:0] startAddress;
reg [ 2:0] rBlink;
reg [ 3:0] bdrColorReg;
reg [ 3:0] pixelWidth; // horizontal pixel width in clock cycles
reg [ 3:0] pixelHeight; // vertical pixel height in scan lines
 
wire [11:0] hctr; // horizontal reference counter (counts clocks since hSync)
wire [11:0] scanline; // scan line
wire [11:0] row; // vertical reference counter (counts rows since vSync)
wire [11:0] col; // horizontal column
reg [ 4:0] rowscan; // scan line within row
wire nxt_row; // when to increment the row counter
wire nxt_col; // when to increment the column counter
wire [ 5:0] bcnt; // blink timing counter
wire blink;
reg iblank;
 
wire nhp; // next horizontal pixel
wire ld_shft = nxt_col & nhp;
 
 
// display and timing signals
reg [15:0] txtAddr; // index into memory
reg [15:0] penAddr;
wire [8:0] txtOut; // character code
wire [8:0] charOut; // character ROM output
wire [8:0] txtBkColor; // background color code
wire [8:0] txtFgColor; // foreground color code
reg [8:0] txtTcCode; // transparent color code
reg bgt;
 
wire [27:0] tdat_o;
wire [8:0] chdat_o;
 
wire [2:0] scanindex = scanline[2:0];
 
//--------------------------------------------------------------------
// Address Decoding
// I/O range Dx
//--------------------------------------------------------------------
wire cs_rom = cs_i && cyc_i && stb_i && (adr_i[15:13]==3'h7);
wire cs_reg = cs_i && cyc_i && stb_i && (adr_i[15: 8]==8'hDF);
wire cs_text = cs_i && cyc_i && stb_i && !adr_i[15];
wire cs_any = cs_i && cyc_i && stb_i;
assign tdat_o[9] = 1'b0;
// Register outputs
always @(posedge clk_i)
if (cs_text) dat_o <= {4'd0,tdat_o};
else if (cs_rom) dat_o <= {23'd0,chdat_o};
else if (cs_reg) dat_o <= {16'd0,rego};
else dat_o <= 32'h0000;
 
//always @(posedge clk_i)
// if (cs_text) begin
// $display("TC WRite: %h %h", adr_i, dat_i);
// $stop;
// end
 
//--------------------------------------------------------------------
// Video Memory
//--------------------------------------------------------------------
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Address Calculation:
// - Simple: the row times the number of cols plus the col plus the
// base screen address
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
wire [17:0] rowcol = row * numCols;
always @(posedge vclk)
txtAddr <= startAddress + rowcol[15:0] + col;
 
// Register read-back memory
wire [3:0] rrm_adr = adr_i[5:2];
wire [15:0] rrm_o;
 
regReadbackMem #(.WID(16)) rrm1
(
.wclk(clk_i),
.adr(rrm_adr),
.wce(cs_reg),
.we(wr_i),
.i(dat_i[15:0]),
.o(rrm_o)
);
 
// text screen RAM
wire [11:0] bram_adr = adr_i[13:2];
syncRam4kx9_1rw1r textRam0
(
.wclk(clk_i),
.wadr(bram_adr),
.i(dat_i[8:0]),
.wo(tdat_o[8:0]),
.wce(cs_text|por),
.we(wr_i|por),
.wrst(1'b0),
 
.rclk(vclk),
.radr(txtAddr[11:0]),
.o(txtOut),
.rce(ld_shft),
.rrst(1'b0)
);
 
// screen attribute RAM
syncRam4kx9_1rw1r fgColorRam
(
.wclk(clk_i),
.wadr(bram_adr),
.i(dat_i[18:10]),
.wo(tdat_o[18:10]),
.wce(cs_text|por),
.we(wr_i|por),
.wrst(1'b0),
 
.rclk(vclk),
.radr(txtAddr[11:0]),
.o(txtFgColor),
.rce(ld_shft),
.rrst(1'b0)
);
 
// screen attribute RAM
syncRam4kx9_1rw1r bkColorRam
(
.wclk(clk_i),
.wadr(bram_adr),
.i(dat_i[27:19]),
.wo(tdat_o[27:19]),
.wce(cs_text|por),
.we(wr_i|por),
.wrst(1'b0),
 
.rclk(vclk),
.radr(txtAddr[11:0]),
.o(txtBkColor),
.rce(ld_shft),
.rrst(1'b0)
);
 
 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Character bitmap ROM
// - room for 512 characters
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
syncRam4kx9_1rw1r charRam0
(
.wclk(clk_i),
.wadr(bram_adr),
.i(dat_i[8:0]),
.wo(chdat_o),
.wce(cs_rom),
.we(1'b0),//we_i),
.wrst(1'b0),
 
.rclk(vclk),
.radr({txtOut,rowscan[2:0]}),
.o(charOut),
.rce(ld_shft),
.rrst(1'b0)
);
 
 
// pipeline delay - sync color with character bitmap output
reg [8:0] txtBkCode1;
reg [8:0] txtFgCode1;
always @(posedge vclk)
if (nhp & ld_shft) txtBkCode1 <= txtBkColor;
always @(posedge vclk)
if (nhp & ld_shft) txtFgCode1 <= txtFgColor;
 
//--------------------------------------------------------------------
// bus interfacing
// - there is a two cycle latency for reads, an ack is generated
// after the synchronous RAM read
// - writes can be acknowledged right away.
//--------------------------------------------------------------------
reg ramRdy,ramRdy1;
always @(posedge clk_i)
begin
ramRdy1 <= cs_any;
ramRdy <= ramRdy1 & cs_any;
end
 
assign ack_o = cs_any ? (wr_i ? 1'b1 : ramRdy) : 1'b0;
 
 
//--------------------------------------------------------------------
// Registers
//
// RW 00 - nnnnnnnn number of columns (horizontal displayed number of characters)
// RW 01 - nnnnnnnn number of rows (vertical displayed number of characters)
// W 02 - n nnnnnnnn window left (horizontal sync position - reference for left edge of displayed)
// W 03 - n nnnnnnnn window top (vertical sync position - reference for the top edge of displayed)
// W 04 - ---nnnnn maximum scan line (char ROM max value is 7)
// W 05 - hhhhwwww pixel size, hhhh=height,wwww=width
// W 07 - n nnnnnnnn transparent color
// W 08 - -BPnnnnn cursor start / blink control
// BP: 00=no blink
// BP: 01=no display
// BP: 10=1/16 field rate blink
// BP: 11=1/32 field rate blink
// W 09 - ----nnnnn cursor end
// W 10 - aaaaaaaa aaaaaaaaa start address (index into display memory)
// W 11 - aaaaaaaa aaaaaaaaa cursor position
// R 12 - aaaaaaaa aaaaaaaaa light pen position
//--------------------------------------------------------------------
 
//--------------------------------------------------------------------
// Light Pen
//--------------------------------------------------------------------
wire lpe;
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(lp), .pe(lpe), .ne(), .ee() );
 
always @(posedge clk_i)
if (rst_i)
penAddr <= 32'h0000_0000;
else begin
if (lpe)
penAddr <= txtAddr;
end
 
 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Register read port
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
always @(cs_reg or cursorPos or penAddr or adr_i or numCols or numRows or rrm_adr or rrm_o)
if (cs_reg) begin
case(rrm_adr)
//4'd0: rego <= numCols;
//4'd1: rego <= numRows;
4'd12: rego <= penAddr;
default: rego <= rrm_o;
endcase
end
else
rego <= 16'h0000;
 
 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Register write port
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
reg interlace;
always @(posedge clk_i)
if (rst_i) begin
por <= 1'b1;
// 104x63
/*
windowTop <= 12'd26;
windowLeft <= 12'd260;
pixelWidth <= 4'd0;
pixelHeight <= 4'd1; // 525 pixels (408 with border)
*/
// 52x31
/*
// 84x47
windowTop <= 12'd16;
windowLeft <= 12'd90;
pixelWidth <= 4'd1; // 681 pixels
pixelHeight <= 4'd1; // 384 pixels
*/
// 56x31
if (num==4'd1) begin
windowTop <= 12'd16;//12'd16;
windowLeft <= 12'h64;//12'd86;
pixelWidth <= 4'd1; // 640 pixels
pixelHeight <= 4'd2; // 256 pixels
numCols <= COLS;
numRows <= ROWS;
maxScanline <= 5'd7;
maxScanpix <= 5'd7;
rBlink <= 3'b111; // 01 = non display
startAddress <= 16'h0000;
cursorStart <= 5'd00;
cursorEnd <= 5'd31;
cursorPos <= 16'h0003;
cursorType <= 2'b00;
txtTcCode <= 9'h1ff;
charOutDelay <= 12'd3;
end
else if (num==4'd2) begin
windowTop <= 12'd64;//12'd16;
windowLeft <= 12'h376;//12'd86;
pixelWidth <= 4'd0; // 680 pixels
pixelHeight <= 4'd1; // 256 pixels
numCols <= 40;
numRows <= 25;
maxScanline <= 5'd7;
maxScanpix <= 5'd7;
rBlink <= 3'b111; // 01 = non display
startAddress <= 16'h0000;
cursorStart <= 5'd00;
cursorEnd <= 5'd31;
cursorPos <= 16'h0003;
cursorType <= 2'b00;
txtTcCode <= 9'h1ff;
charOutDelay <= 12'd3;
end
end
else begin
if (cs_reg & wr_i) begin // register write ?
$display("TC Write: r%d=%h", rrm_adr, dat_i);
case(rrm_adr)
4'd00: begin
numCols <= dat_i[11:0]; // horizontal displayed
charOutDelay <= dat_i[15:12];
end
4'd01: numRows <= dat_i;
4'd02: windowLeft <= dat_i[11:0];
4'd03: windowTop <= dat_i[11:0]; // vertical sync position
4'd04: maxScanline <= dat_i[4:0];
4'd05: begin
pixelHeight <= dat_i[7:4];
pixelWidth <= dat_i[3:0]; // horizontal pixel width
end
4'd06: por <= dat_i[0];
4'd07: txtTcCode <= dat_i[8:0];
4'd08: begin
cursorStart <= dat_i[4:0]; // scan line sursor starts on
rBlink <= dat_i[7:5];
cursorType <= dat_i[9:8];
end
4'd09: cursorEnd <= dat_i[4:0]; // scan line cursor ends on
4'd10: startAddress <= dat_i;
4'd11: cursorPos <= dat_i[15:0];
default: ;
endcase
end
end
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
 
// "Box" cursor bitmap
reg [7:0] curout;
always @(scanindex or cursorType)
case({cursorType,scanindex})
// Box cursor
5'b00_000: curout = 8'b11111111;
5'b00_001: curout = 8'b10000001;
5'b00_010: curout = 8'b10000001;
5'b00_011: curout = 8'b10000001;
5'b00_100: curout = 8'b10000001;
5'b00_101: curout = 8'b10000001;
5'b00_110: curout = 8'b10011001;
5'b00_111: curout = 8'b11111111;
// vertical bar cursor
5'b01_000: curout = 8'b11000000;
5'b01_001: curout = 8'b10000000;
5'b01_010: curout = 8'b10000000;
5'b01_011: curout = 8'b10000000;
5'b01_100: curout = 8'b10000000;
5'b01_101: curout = 8'b10000000;
5'b01_110: curout = 8'b10000000;
5'b01_111: curout = 8'b11000000;
// underline cursor
5'b10_000: curout = 8'b00000000;
5'b10_001: curout = 8'b00000000;
5'b10_010: curout = 8'b00000000;
5'b10_011: curout = 8'b00000000;
5'b10_100: curout = 8'b00000000;
5'b10_101: curout = 8'b00000000;
5'b10_110: curout = 8'b00000000;
5'b10_111: curout = 8'b11111111;
// Asterisk
5'b11_000: curout = 8'b00000000;
5'b11_001: curout = 8'b00000000;
5'b11_010: curout = 8'b00100100;
5'b11_011: curout = 8'b00011000;
5'b11_100: curout = 8'b01111110;
5'b11_101: curout = 8'b00011000;
5'b11_110: curout = 8'b00100100;
5'b11_111: curout = 8'b00000000;
endcase
 
 
//-------------------------------------------------------------
// Video Stuff
//-------------------------------------------------------------
 
wire pe_hsync;
wire pe_vsync;
edge_det edh1
(
.rst(rst_i),
.clk(vclk),
.ce(1'b1),
.i(hsync),
.pe(pe_hsync),
.ne(),
.ee()
);
 
edge_det edv1
(
.rst(rst_i),
.clk(vclk),
.ce(1'b1),
.i(vsync),
.pe(pe_vsync),
.ne(),
.ee()
);
 
// Horizontal counter:
//
HVCounter uhv1
(
.rst(rst_i),
.vclk(vclk),
.pixcce(1'b1),
.sync(hsync),
.cnt_offs(windowLeft),
.pixsz(pixelWidth),
.maxpix(maxScanpix),
.nxt_pix(nhp),
.pos(col),
.nxt_pos(nxt_col),
.ctr(hctr)
);
 
 
// Vertical counter:
//
HVCounter uhv2
(
.rst(rst_i),
.vclk(vclk),
.pixcce(pe_hsync),
.sync(vsync),
.cnt_offs(windowTop),
.pixsz(pixelHeight),
.maxpix(maxScanline),
.nxt_pix(),
.pos(row),
.nxt_pos(nxt_row),
.ctr(scanline)
);
 
always @(posedge vclk)
rowscan <= scanline - row * (maxScanline+1);
 
 
// Blink counter
//
VT163 #(6) ub1
(
.clk(vclk),
.clr_n(!rst_i),
.ent(pe_vsync),
.enp(1'b1),
.ld_n(1'b1),
.d(6'd0),
.q(bcnt),
.rco()
);
 
wire blink_en = (cursorPos+2==txtAddr) && (scanline[4:0] >= cursorStart) && (scanline[4:0] <= cursorEnd);
 
VT151 ub2
(
.e_n(!blink_en),
.s(rBlink),
.i0(1'b1), .i1(1'b0), .i2(bcnt[4]), .i3(bcnt[5]),
.i4(1'b1), .i5(1'b0), .i6(bcnt[4]), .i7(bcnt[5]),
.z(blink),
.z_n()
);
 
always @(posedge vclk)
if (nhp & ld_shft)
bkColor24 <= {txtBkCode1[8:6],5'h10,txtBkCode1[5:3],5'h10,txtBkCode1[2:0],5'h10};
always @(posedge vclk)
if (nhp & ld_shft)
fgColor24 <= {txtFgCode1[8:6],5'h10,txtFgCode1[5:3],5'h10,txtFgCode1[2:0],5'h10};
 
always @(posedge vclk)
if (nhp & ld_shft)
bgt <= txtBkCode1==txtTcCode;
 
 
// Convert character bitmap to pixels
// For convenience, the character bitmap data in the ROM is in the
// opposite bit order to what's needed for the display. The following
// just alters the order without adding any hardware.
//
wire [7:0] charRev = {
charOut[0],
charOut[1],
charOut[2],
charOut[3],
charOut[4],
charOut[5],
charOut[6],
charOut[7]
};
 
wire [7:0] charout1 = blink ? (charRev ^ curout) : charRev;
 
// Convert parallel to serial
ParallelToSerial ups1
(
.rst(rst_i),
.clk(vclk),
.ce(nhp),
.ld(ld_shft),
.qin(1'b0),
.d(charout1),
.qh(pix)
);
 
reg pix1;
always @(posedge vclk)
if (nhp)
pix1 <= pix;
 
// Pipelining Effect:
// - character output is delayed by 2 or 3 character times relative to the video counters
// depending on the resolution selected
// - this means we must adapt the blanking signal by shifting the blanking window
// two or three character times.
wire bpix = hctr[1] ^ scanline[4];// ^ blink;
always @(posedge vclk)
if (nhp)
iblank <= (row >= numRows) || (col >= numCols + charOutDelay) || (col < charOutDelay);
 
// Choose between input RGB and controller generated RGB
// Select between foreground and background colours.
always @(posedge vclk)
if (nhp) begin
casex({blank,iblank,border,bpix,pix1})
5'b1xxxx: rgbOut <= 25'h0000000;
5'b01xxx: rgbOut <= rgbIn;
5'b0010x: rgbOut <= 24'hBF2020;
5'b0011x: rgbOut <= 24'hDFDFDF;
5'b000x0: rgbOut <= bgt ? rgbIn : bkColor24;
5'b000x1: rgbOut <= fgColor24;
endcase
end
 
endmodule
 
/rtl/bench/soc/video/HVCounter.v
0,0 → 1,161
`timescale 1ns / 1ps
// ============================================================================
// 2011 Robert Finch
// robfinch@<remove>sympatico.ca
//
// HVCounter.v
// Horizontal / Vertical counter:
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// ============================================================================
 
// horizontal pixel prescale counter
// Each pixel may be multiple clocks wide
//
// 37 slices / 64 LUTs / 161.525 MHz
// 28 ff's / 1 Mult
 
module HVCounter(
rst, vclk, pixcce, sync, cnt_offs, pixsz, maxpix, nxt_pix, pos, nxt_pos, ctr
);
input rst;
input vclk; // video clock
input pixcce; // pixel counter clock enable
input sync; // synchronization input (eol or eof)
input [11:0] cnt_offs; // counter offset: top or left of display area
input [3:0] pixsz; // size of a pixel in video clock
input [4:0] maxpix; // maximum pixels for width / height of character
output nxt_pix; // when the next pixel will happen
output [11:0] pos; // current row or column position
output nxt_pos; // flag: when the row or column is about to change
output [11:0] ctr; // counter output
 
reg [11:0] pos;
reg [11:0] ctr;
reg nxt_pix;
 
wire [11:0] ctr1;
wire nxp;
reg [23:0] x4096;
wire pe_sync;
 
// Lookup reciprocal of number of pixels per character
// - used to calculate the column position
reg [11:0] inv;
always @(posedge vclk)
case(maxpix)
5'd00: inv <= 12'd4095;
5'd01: inv <= 12'd2048;
5'd02: inv <= 12'd1365;
5'd03: inv <= 12'd1024;
5'd04: inv <= 12'd0819;
5'd05: inv <= 12'd0683;
5'd06: inv <= 12'd0585;
5'd07: inv <= 12'd0512;
5'd08: inv <= 12'd0455;
5'd09: inv <= 12'd0409;
5'd10: inv <= 12'd0372;
5'd11: inv <= 12'd0341;
5'd12: inv <= 12'd0315;
5'd13: inv <= 12'd0292;
5'd14: inv <= 12'd0273;
5'd15: inv <= 12'd0256;
5'd16: inv <= 12'd0240;
5'd17: inv <= 12'd0227;
5'd18: inv <= 12'd0215;
5'd19: inv <= 12'd0204;
5'd20: inv <= 12'd0195;
5'd21: inv <= 12'd0186;
5'd22: inv <= 12'd0178;
5'd23: inv <= 12'd0170;
5'd24: inv <= 12'd0163;
5'd25: inv <= 12'd0157;
5'd26: inv <= 12'd0151;
5'd27: inv <= 12'd0146;
5'd28: inv <= 12'd0141;
5'd29: inv <= 12'd0136;
5'd30: inv <= 12'd0132;
5'd31: inv <= 12'd0128;
endcase
 
 
// Calculate character position
// - divide the raw count by the number of pixels per character
// - done by multiplying by the reciprocal
always @(posedge vclk)
x4096 <= ctr * inv;
always @(x4096)
pos <= x4096[23:12];
always @(posedge vclk) // pipeline delay
ctr <= ctr1;
always @(posedge vclk)
nxt_pix <= nxp;
 
edge_det u4
(
.rst(rst),
.clk(vclk),
.ce(1'b1),
.i(sync),
.pe(pe_sync),
.ne(),
.ee()
);
 
// Pixel width counter
// Controls number of clock cycles per pixel
VT163 #(4) u1
(
.clk(vclk),
.clr_n(!rst),
.ent(pixcce),
.enp(1'b1),
.ld_n(!pe_sync & !nxp), // synchronize count to start of scan
.d(4'hF-pixsz),
.q(),
.rco(nxp)
);
 
 
// Pixel counter
// - raw pixel count
// - just increments every time the nxt_pix signal is active
// - synchronized to the end-of-line or end-of-frame signal
VT163 #(12) u2
(
.clk(vclk),
.clr_n(!rst),
.ent(nxp),
.enp(1'b1),
.ld_n(!pe_sync), // synchronize count to start of scan
.d(12'h000-cnt_offs),
.q(ctr1),
.rco()
);
 
 
// Detect when the position changes
// - compare current pos to previous pos when the position might change
change_det #(12) u3
(
.rst(rst),
.clk(vclk),
.ce(nxt_pix),
.i(pos),
.cd(nxt_pos)
);
 
endmodule
/rtl/bench/soc/video/WXGASyncGen1280x768_60Hz.v
0,0 → 1,92
// ============================================================================
// (C) 2012-2017 Robert Finch
//
// WXGASyncGen1280x768_60Hz.v
// WXGA sync generator
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
//
//
// WXGA video sync generator.
//
// Input clock: 80.00 MHz (100 MHz * 12/15)
// Horizontal freq: 47.7 kHz (generated) (47.619KHz)
// Vertical freq: 60.00 Hz (generated) (59.89 Hz)
//
// This module generates the basic sync timing signals required for a
// WXGA display.
//
// ============================================================================
 
module WXGASyncGen1280x768_60Hz(rst, clk, hSync, vSync, blank, border);
parameter phSyncOn = 67; // 72 front porch
parameter phSyncOff = 201; // 144 sync
parameter phBlankOff = 400; // 212 back porch
parameter phBorderOff = 400; // 0 border
parameter phBorderOn = 1680; // 1366 display
parameter phBlankOn = 1680; // 0 border
parameter phTotal = 1680; // 1800 total clocks
// 47.7 = 60 * 795 kHz
parameter pvSyncOn = 2; // 1 front porch
parameter pvSyncOff = 5; // 3 vertical sync
parameter pvBlankOff = 27; // 23 back porch
parameter pvBorderOff = 27; // 2 border 0
parameter pvBorderOn = 795; // 768 display
parameter pvBlankOn = 795; // 1 border 0
parameter pvTotal = 795; // 795 total scan lines
// 60 Hz
// 1280x768
input rst; // reset
input clk; // video clock
output reg hSync, vSync; // sync outputs
output blank; // blanking output
output border;
 
//---------------------------------------------------------------------
//---------------------------------------------------------------------
 
wire [11:0] hCtr; // count from 1 to 1800
wire [11:0] vCtr; // count from 1 to 795
 
wire vBlank, hBlank;
wire vBorder,hBorder;
wire hSync1,vSync1;
reg blank;
reg border;
 
wire eol = hCtr==phTotal;
wire eof = vCtr==pvTotal && eol;
 
assign vSync1 = vCtr >= pvSyncOn && vCtr < pvSyncOff;
assign hSync1 = !(hCtr >= phSyncOn && hCtr < phSyncOff);
assign vBlank = vCtr >= pvBlankOn || vCtr < pvBlankOff;
assign hBlank = hCtr >= phBlankOn || hCtr < phBlankOff;
assign vBorder = vCtr >= pvBorderOn || vCtr < pvBorderOff;
assign hBorder = hCtr >= phBorderOn || hCtr < phBorderOff;
 
counter #(12) u1 (.rst(rst), .clk(clk), .ce(1'b1), .ld(eol), .d(12'd1), .q(hCtr), .tc() );
counter #(12) u2 (.rst(rst), .clk(clk), .ce(eol), .ld(eof), .d(12'd1), .q(vCtr), .tc() );
 
always @(posedge clk)
blank <= #1 hBlank|vBlank;
always @(posedge clk)
border <= #1 hBorder|vBorder;
always @(posedge clk)
hSync <= #1 hSync1;
always @(posedge clk)
vSync <= #1 vSync1;
 
endmodule
 
/rtl/bench/soc/video/rtfColorROM.v
0,0 → 1,110
// ============================================================================
// 2006-2011 Robert Finch
// robfinch@<remove>sympatico.ca
//
// rtfColorROM.v
// Color lookup ROM for TextController.
// Converts a 5-bit color code to a 24 bit RGB value.
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// ============================================================================
 
 
// TC64 color codes
`define TC64_BLACK 5'd0
`define TC64_WHITE 5'd1
`define TC64_RED 5'd2
`define TC64_CYAN 5'd3
`define TC64_PURPLE 5'd4
`define TC64_GREEN 5'd5
`define TC64_BLUE 5'd6
`define TC64_YELLOW 5'd7
`define TC64_ORANGE 5'd8
`define TC64_BROWN 5'd9
`define TC64_PINK 5'd10
`define TC64_DARK_GREY 5'd11
`define TC64_MEDIUM_GREY 5'd12
`define TC64_LIGHT_GREEN 5'd13
`define TC64_LIGHT_BLUE 5'd14
`define TC64_LIGHT_GREY 5'd15
 
`define TC64_BLACKa 5'd16
`define TC64_WHITEa 5'd17
`define TC64_REDa 5'd18
`define TC64_CYANa 5'd19
`define TC64_PURPLEa 5'd20
`define TC64_GREENa 5'd21
`define TC64_BLUEa 5'd22
`define TC64_YELLOWa 5'd23
`define TC64_ORANGEa 5'd24
`define TC64_BROWNa 5'd25
`define TC64_PINKa 5'd26
`define TC64_DARK_GREYa 5'd27
`define TC64_GREY3 5'd28
`define TC64_LIGHT_GREENa 5'd29
`define TC64_LIGHT_BLUEa 5'd30
`define TC64_GREY5 5'd31
 
module rtfColorROM(clk, ce, code, color);
input clk;
input ce;
input [4:0] code;
output [23:0] color;
reg [23:0] color;
 
always @(posedge clk)
if (ce) begin
case (code)
`TC64_BLACK: color = 24'h10_10_10;
`TC64_WHITE: color = 24'hFF_FF_FF;
`TC64_RED: color = 24'hE0_40_40;
`TC64_CYAN: color = 24'h60_FF_FF;
`TC64_PURPLE: color = 24'hE0_60_E0;
`TC64_GREEN: color = 24'h40_E0_40;
`TC64_BLUE: color = 24'h40_40_E0;
`TC64_YELLOW: color = 24'hFF_FF_40;
`TC64_ORANGE: color = 24'hE0_A0_40;
`TC64_BROWN: color = 24'h9C_74_48;
`TC64_PINK: color = 24'hFF_A0_A0;
`TC64_DARK_GREY: color = 24'h54_54_54;
`TC64_MEDIUM_GREY: color = 24'h88_88_88;
`TC64_LIGHT_GREEN: color = 24'hA0_FF_A0;
`TC64_LIGHT_BLUE: color = 24'hA0_A0_FF;
`TC64_LIGHT_GREY: color = 24'hC0_C0_C0;
 
`TC64_BLACKa: color = 24'h10_10_10;
`TC64_WHITEa: color = 24'hFF_FF_FF;
`TC64_REDa: color = 24'hE0_40_40;
`TC64_CYANa: color = 24'h60_FF_FF;
`TC64_PURPLEa: color = 24'hE0_60_E0;
`TC64_GREENa: color = 24'h40_E0_40;
`TC64_BLUEa: color = 24'h40_40_E0;
`TC64_YELLOWa: color = 24'hFF_FF_40;
`TC64_ORANGEa: color = 24'hE0_A0_40;
`TC64_BROWNa: color = 24'h9C_74_48;
`TC64_PINKa: color = 24'hFF_A0_A0;
`TC64_DARK_GREYa: color = 24'h54_54_54;
`TC64_GREY3: color = 24'h30_30_30;
`TC64_LIGHT_GREENa: color = 24'hA0_FF_A0;
`TC64_LIGHT_BLUEa: color = 24'hA0_A0_FF;
`TC64_GREY5: color = 24'h50_50_50;
 
endcase
end
 
endmodule
 
 
/rtl/lib/ParallelToSerial.v
0,0 → 1,47
// ============================================================================
// 2006,2007,2011 Robert Finch
// robfinch@<remove>sympatico.ca
//
// ParallelToSerial.v
// Parallel to serial data converter (shift register).
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 ParallelToSerial(rst, clk, ce, ld, qin, d, qh);
parameter WID=8;
input rst; // reset
input clk; // clock
input ce; // clock enable
input ld; // load
input qin; // serial shifting input
input [WID:1] d; // data to load
output qh; // serial output
 
reg [WID:1] q;
 
always @(posedge clk)
if (rst)
q <= 0;
else if (ce) begin
if (ld)
q <= d;
else
q <= {q[WID-1:1],qin};
end
 
assign qh = q[WID];
 
endmodule
/rtl/lib/VT151.v
0,0 → 1,56
// ============================================================================
// 2007 Robert Finch
// robfinch@<remove>sympatico.ca
//
// 74LS151 mux
// 8-to-1 mux with enable
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 VT151(e_n, s, i0, i1, i2, i3, i4, i5, i6, i7, z, z_n);
parameter WID=1;
input e_n;
input [2:0] s;
input [WID:1] i0;
input [WID:1] i1;
input [WID:1] i2;
input [WID:1] i3;
input [WID:1] i4;
input [WID:1] i5;
input [WID:1] i6;
input [WID:1] i7;
output [WID:1] z;
output [WID:1] z_n;
 
reg [WID:1] z;
 
always @(e_n or s or i0 or i1 or i2 or i3 or i4 or i5 or i6 or i7)
case({e_n,s})
4'b0000: z <= i0;
4'b0001: z <= i1;
4'b0010: z <= i2;
4'b0011: z <= i3;
4'b0100: z <= i4;
4'b0101: z <= i5;
4'b0110: z <= i6;
4'b0111: z <= i7;
default: z <= {WID{1'b0}};
endcase
 
assign z_n = ~z;
 
endmodule
/rtl/lib/VT163.v
0,0 → 1,50
// ============================================================================
// 2007 Robert Finch
// robfinch@<remove>sympatico.ca
//
// VT163 - 74LS163 counter
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
// ============================================================================
//
// Webpack 9.1i xc3s1000-4ft256
// 4 slices / 8 LUTs / 324.675 MHz
 
module VT163(clk, clr_n, ent, enp, ld_n, d, q, rco);
parameter WID=4;
input clk;
input clr_n; // clear active low
input ent; // clock enable
input enp; // clock enable
input ld_n; // load active low
input [WID:1] d;
output [WID:1] q;
reg [WID:1] q;
output rco;
 
assign rco = &{q[WID:1],ent};
 
always @(posedge clk)
begin
if (!clr_n)
q <= {WID{1'b0}};
else if (!ld_n)
q <= d;
else if (enp & ent)
q <= q + {{WID-1{1'b0}},1'b1};
end
 
endmodule
/rtl/lib/change_det.v
0,0 → 1,41
// ============================================================================
// 2006 Robert Finch
// robfinch@<remove>sympatico.ca
//
// change_det.v
// - detects a change in a value
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 change_det(rst, clk, ce, i, cd);
parameter WID=32;
input rst; // reset
input clk; // clock
input ce; // clock enable
input [WID:1] i; // input signal
output cd; // change detected
 
reg [WID:1] hold;
 
always @(posedge clk)
if (rst)
hold <= i;
else if (ce)
hold <= i;
 
assign cd = i != hold;
 
endmodule
/rtl/lib/counter.v
0,0 → 1,49
// ============================================================================
// (C) 2007 Robert Finch
// All Rights Reserved.
//
// counter.v
// generic up counter
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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 counter(rst, clk, ce, ld, d, q, tc);
parameter WID=8;
parameter pMaxCnt={WID{1'b1}};
input rst;
input clk;
input ce;
input ld;
input [WID:1] d;
output [WID:1] q;
reg [WID:1] q;
output tc;
 
assign tc = &q;
 
always @(posedge clk)
if (rst)
q <= 1'b0;
else if (ce) begin
if (ld)
q <= d;
else if (tc)
q <= 1'b0;
else
q <= q + 1'b1;
end
 
endmodule
/rtl/lib/down_counter.v
0,0 → 1,58
// ============================================================================
// down_counter.v
// - counts down
//
//
// 2010 Robert Finch
// pfingh>remove<@birdcomputer.ca
//
//
// This source code is available for evaluation and validation purposes
// only. This copyright statement and disclaimer must remain present in
// the file.
//
//
// NO WARRANTY.
// THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
// EXPRESS OR IMPLIED. The user must assume the entire risk of using the
// Work.
//
// IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
// INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
// THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
//
// IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
// IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
// REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
// LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
// AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
// LOSSES RELATING TO SUCH UNAUTHORIZED USE.
//
//
// Verilog 1995
// ============================================================================
 
module down_counter(rst, clk, ce, ld, d, q, z);
parameter WID=8;
input rst;
input clk;
input ce;
input ld;
input [WID:1] d;
output [WID:1] q;
reg [WID:1] q;
output z;
 
always @(posedge clk)
if (rst)
q <= 0;
else if (ce) begin
if (ld)
q <= d;
else
q <= q + {WID{1'b1}};
end
 
assign z = q == 0;
 
endmodule
/rtl/lib/vtdl.v
0,0 → 1,59
//=============================================================================
// (C) 2007,2012 Robert Finch, Stratford
// robfinch<remove>@opencores.org
//
//
// vtdl - variable tap delay line
// (dynamic shift register)
//
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 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/>.
//
//
// Notes:
//
// This module acts like a clocked delay line with a variable tap.
// Miscellaneous usage in rate control circuitry such as fifo's.
// Capable of delaying a signal bus.
// Signal bus width is specified with the WID parameter.
//
// Verilog 1995
// Ref: Webpack9.1i xc3s1000-4ft256
// 4 slices / 8 LUTs / < 10ns
//=============================================================================
//
module vtdl(clk, ce, a, d, q);
parameter WID = 8;
parameter DEP = 16;
localparam AMSB = DEP>64?6:DEP>32?5:DEP>16?4:DEP>8?3:DEP>4?2:DEP>2?1:0;
input clk;
input ce;
input [AMSB:0] a;
input [WID-1:0] d;
output [WID-1:0] q;
 
reg [WID-1:0] m [DEP-1:0];
integer n;
 
always @(posedge clk)
if (ce) begin
for (n = 1; n < DEP; n = n + 1)
m[n] <= m[n-1];
m[0] <= d;
end
 
assign q = m[a];
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.