1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-09 01:11:20 +00:00

Archie: replace vidc fifo with DCFIFO component to fix clock domain crossing issues

This commit is contained in:
Gyorgy Szombathelyi
2019-10-19 16:58:30 +02:00
parent 53d8613015
commit 39fafc65b8
6 changed files with 248 additions and 234 deletions

View File

@@ -136,7 +136,7 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to DRAM_*
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE output_files/fdc.stp
set_global_assignment -name USE_SIGNALTAP_FILE output_files/vidc.stp
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_NCE_PIN OFF
@@ -177,7 +177,7 @@ set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to DRAM_DQ[*]
set_global_assignment -name SEED 1
set_global_assignment -name ENABLE_DRC_SETTINGS OFF
set_location_assignment PLL_1 -to CLOCKS|altpll_component|auto_generated|pll1
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
set_global_assignment -name VERILOG_FILE archimedes_mist_top.v
set_global_assignment -name SYSTEMVERILOG_FILE rgb2ypbpr.sv
set_global_assignment -name VERILOG_FILE sigma_delta_dac.v
@@ -192,8 +192,6 @@ set_global_assignment -name VERILOG_FILE ../../rtl/fdc1772.v
set_global_assignment -name VERILOG_FILE ../../rtl/latches.v
set_global_assignment -name VERILOG_FILE ../../rtl/floppy.v
set_global_assignment -name VERILOG_FILE ../../rtl/podules.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_audio.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_dmachannel.v
set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/serialInterface.v
set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/registerInterface.v
set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/i2cSlaveTop.v
@@ -202,7 +200,9 @@ set_global_assignment -name VERILOG_FILE ../../rtl/ioc_irq.v
set_global_assignment -name VERILOG_FILE ../../rtl/ioc.v
set_global_assignment -name VERILOG_FILE ../../rtl/amber/a23_barrel_shift.v
set_global_assignment -name VERILOG_FILE ../../rtl/memc_translator.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_fifo.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_audio.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_dmachannel.v
set_global_assignment -name QIP_FILE ../../rtl/vidc_dcfifo.qip
set_global_assignment -name VERILOG_FILE ../../rtl/vidc_timing.v
set_global_assignment -name VERILOG_FILE ../../rtl/vidc.v
set_global_assignment -name VERILOG_FILE ../../rtl/por.v

View File

@@ -40,8 +40,8 @@ module vidc(
// dma control.
input [31:0] viddat,
input vidak,
output vidrq,
output vidrq,
input sndak,
output sndrq,
@@ -102,6 +102,7 @@ wire snd_load;
// internal data request lines
wire currq_int;
wire vidrq_int;
reg hsync_cpu;
reg cepix;
@@ -157,15 +158,15 @@ vidc_dmachannel VIDEODMA (
.rq ( vidrq_int ),
.busy ( vid_load ),
.stall ( ~hsync ),
.stall ( ~hsync_cpu ),
.dev_data ( pix_data ),
.dev_ak ( pix_ack )
);
// this module does the math for a DMA channel
vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA (
vidc_dmachannel #(.FIFO4WORDS(1'b1)) CURSORDMA (
.rst ( flybk | rst_i ),
.clkcpu ( clkcpu ),
@@ -178,7 +179,7 @@ vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA (
.rq ( currq_int ),
.busy ( cur_load ),
.stall ( hsync | vid_load ),
.stall ( hsync_cpu | vid_load ),
.dev_data ( csr_data ),
.dev_ak ( csr_ack )
@@ -186,7 +187,7 @@ vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA (
);
// this module does the math for a DMA channel
vidc_dmachannel SOUNDDMA (
vidc_dmachannel #(.FIFO4WORDS(1'b1)) SOUNDDMA (
.rst ( rst_i ),
.clkcpu ( clkcpu ),
@@ -386,7 +387,8 @@ assign video_b[2:0] = vidc_colour[10:8];
assign video_en = enabled;
// this demux's the two dma channels that share the vidrq.
assign vidrq = hsync ? vidrq_int : ~vid_load & currq_int;
// this demux's the two dma channels that share the vidrq.
always @(posedge clkcpu) hsync_cpu <= hsync; // transfer hsync to cpu clock domain
assign vidrq = hsync_cpu ? vidrq_int : ~vid_load & currq_int;
endmodule

View File

@@ -0,0 +1,3 @@
set_global_assignment -name IP_TOOL_NAME "FIFO"
set_global_assignment -name IP_TOOL_VERSION "13.1"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "vidc_dcfifo.v"]

View File

@@ -0,0 +1,179 @@
// megafunction wizard: %FIFO%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: dcfifo_mixed_widths
// ============================================================
// File Name: vidc_dcfifo.v
// Megafunction Name(s):
// dcfifo_mixed_widths
//
// 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 Patches 4.26 SJ Web Edition
// ************************************************************
//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 vidc_dcfifo (
aclr,
data,
rdclk,
rdreq,
wrclk,
wrreq,
q,
wrusedw);
input aclr;
input [31:0] data;
input rdclk;
input rdreq;
input wrclk;
input wrreq;
output [7:0] q;
output [3:0] wrusedw;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 aclr;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [7:0] sub_wire0;
wire [3:0] sub_wire1;
wire [7:0] q = sub_wire0[7:0];
wire [3:0] wrusedw = sub_wire1[3:0];
dcfifo_mixed_widths dcfifo_mixed_widths_component (
.aclr (aclr),
.data (data),
.rdclk (rdclk),
.rdreq (rdreq),
.wrclk (wrclk),
.wrreq (wrreq),
.q (sub_wire0),
.wrusedw (sub_wire1),
.rdempty (),
.rdfull (),
.rdusedw (),
.wrempty (),
.wrfull ());
defparam
dcfifo_mixed_widths_component.add_usedw_msb_bit = "ON",
dcfifo_mixed_widths_component.intended_device_family = "Cyclone III",
dcfifo_mixed_widths_component.lpm_numwords = 8,
dcfifo_mixed_widths_component.lpm_showahead = "OFF",
dcfifo_mixed_widths_component.lpm_type = "dcfifo_mixed_widths",
dcfifo_mixed_widths_component.lpm_width = 32,
dcfifo_mixed_widths_component.lpm_widthu = 4,
dcfifo_mixed_widths_component.lpm_widthu_r = 6,
dcfifo_mixed_widths_component.lpm_width_r = 8,
dcfifo_mixed_widths_component.overflow_checking = "ON",
dcfifo_mixed_widths_component.rdsync_delaypipe = 4,
dcfifo_mixed_widths_component.read_aclr_synch = "ON",
dcfifo_mixed_widths_component.underflow_checking = "ON",
dcfifo_mixed_widths_component.use_eab = "ON",
dcfifo_mixed_widths_component.write_aclr_synch = "ON",
dcfifo_mixed_widths_component.wrsync_delaypipe = 4;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
// Retrieval info: PRIVATE: Clock NUMERIC "4"
// Retrieval info: PRIVATE: Depth NUMERIC "8"
// Retrieval info: PRIVATE: Empty NUMERIC "1"
// Retrieval info: PRIVATE: Full NUMERIC "1"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: Optimize NUMERIC "0"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: UsedW NUMERIC "1"
// Retrieval info: PRIVATE: Width NUMERIC "32"
// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
// Retrieval info: PRIVATE: diff_widths NUMERIC "1"
// Retrieval info: PRIVATE: msb_usedw NUMERIC "1"
// Retrieval info: PRIVATE: output_width NUMERIC "8"
// Retrieval info: PRIVATE: rsEmpty NUMERIC "0"
// Retrieval info: PRIVATE: rsFull NUMERIC "0"
// Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
// Retrieval info: PRIVATE: wsFull NUMERIC "0"
// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADD_USEDW_MSB_BIT STRING "ON"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "8"
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo_mixed_widths"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32"
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "4"
// Retrieval info: CONSTANT: LPM_WIDTHU_R NUMERIC "6"
// Retrieval info: CONSTANT: LPM_WIDTH_R NUMERIC "8"
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4"
// Retrieval info: CONSTANT: READ_ACLR_SYNCH STRING "ON"
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
// Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "ON"
// Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4"
// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND "aclr"
// Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]"
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
// Retrieval info: USED_PORT: wrusedw 0 0 4 0 OUTPUT NODEFVAL "wrusedw[3..0]"
// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
// Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0
// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
// Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
// Retrieval info: CONNECT: wrusedw 0 0 4 0 @wrusedw 0 0 4 0
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@@ -26,124 +26,97 @@
* (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 vidc_dmachannel
(
input clkcpu,
input clkdev,
input cedev,
input rst,
// dma bus
input clkcpu,
input ak,
output reg rq,
input [31:0] cpu_data,
input rst,
// dma bus
input ak,
output reg rq,
input [31:0] cpu_data,
output busy,
input stall, // dont start another request with this high.
// device bus
// device bus
input clkdev,
input cedev,
input dev_ak,
output [7:0] dev_data
);
// 8 or 4 words fifo
parameter FIFO4WORDS = 1'b0;
parameter FIFO_SIZE = 3;
localparam MEM_DEPTH = 2**FIFO_SIZE;
localparam WORD_WIDTH = FIFO_SIZE;
localparam BYTE_WIDTH = FIFO_SIZE + 2;
localparam HALF_FULL = 1<<(WORD_WIDTH-1);
reg [1:0] dma_count = 2'd0;
reg load = 1'b0;
wire fifo_can_load;
wire [3:0] wrusedw;
reg [1:0] dma_count = 2'd0;
reg load = 1'b0;
reg ak_r = 1'b0;
// each channel has a fifo of a different size.
wire [WORD_WIDTH-1:0] wr_ptr;
wire [WORD_WIDTH-1:0] space;
wire full;
wire fifo_can_load;
initial begin
rq = 1'b0;
end
vidc_fifo #(.FIFO_SIZE(FIFO_SIZE)) VIDEO_FIFO(
.rst ( rst ),
.wr_clk ( clkcpu ),
.rd_clk ( clkdev ),
.rd_ce ( cedev ),
.wr_en ( ak & load ),
.rd_en ( dev_ak ),
.din ( cpu_data ),
.dout ( dev_data ),
.wr_ptr ( wr_ptr ),
.space ( space ),
.full ( full )
);
vidc_dcfifo VIDEO_FIFO(
.aclr ( rst ),
.data ( cpu_data ),
.rdclk ( clkdev ),
.rdreq ( cedev & dev_ak ),
.wrclk ( clkcpu ),
.wrreq ( ak & load ),
.q ( dev_data ),
.wrusedw( wrusedw )
);
// DMA interface control
// this is in the cpu clock domain.
always @(posedge clkcpu) begin
reg rstD, rstD2;
ak_r <= ak;
rstD <= rst;
rstD2 <= rstD;
if (rstD2 == 1'b1) begin
// do reset logic
dma_count <= 2'd0;
load <= 1'b0;
rq <= 1'b0;
end else begin
// if the load is in progress
if ((load == 1'b1) & (ak == 1'b1)) begin
if (ak & load) begin
// are we done?
if (dma_count == 2'd3) begin
load <= 1'b0;
end
if (dma_count == 2'd3) load <= 1'b0;
// clear the request on the first ack.
// the dma action will continue until 4 words are read.
rq <= 1'b0;
// count the ack pulses
dma_count <= dma_count + 2'd1;
end else if (load == 1'b0) begin
end else if (~load) begin
// possibly unnecessary?
dma_count <= 2'd0;
// if the fifo can load and its our slot then go.
if (fifo_can_load === 1'b1) begin
load <= 1'b1;
rq <= 1'b1;
end
end
// if the fifo can load and its our slot then go.
if (fifo_can_load === 1'b1) begin
load <= 1'b1;
rq <= 1'b1;
end
end
end
// TODO: replace 2'b00 with bits 4 and 5 of fifo control register for video fifo.
assign fifo_can_load = ~stall & ((space > 3'd4) | ((space == 'd0) & (full == 1'b0))) & (wr_ptr[1:0] == 2'b00);
assign busy = load;
// TODO: use bits 4 and 5 of fifo control register for requesting new data to the video fifo.
// But the RAM timing is so different from the original machine that it won't be useful
assign fifo_can_load = ~stall && ((!FIFO4WORDS && wrusedw <= 4) || (FIFO4WORDS && wrusedw == 0));
assign busy = load;
endmodule

View File

@@ -1,143 +0,0 @@
`timescale 1ns / 1ps
/* vidc_fifo.v
Copyright (c) 2012-2014, Stephen J. Leary
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.
* * Neither the name of the <organization> nor the
* names of its contributors may 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 <COPYRIGHT HOLDER> 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 vidc_fifo #(
parameter FIFO_SIZE = 3
)
(
input rst,
input wr_clk,
input wr_en,
input[31:0] din,
input rd_clk,
input rd_ce,
input rd_en,
output reg [7:0] dout,
output reg [WORD_WIDTH-1:0] wr_ptr,
output reg [WORD_WIDTH-1:0] space,
output reg full,
output empty
);
localparam MEM_DEPTH = 2**FIFO_SIZE;
localparam WORD_WIDTH = FIFO_SIZE;
localparam BYTE_WIDTH = FIFO_SIZE + 2;
reg [31:0] data[0:MEM_DEPTH-1];
reg [BYTE_WIDTH-1:0] rd_ptr;
integer k;
initial begin
wr_ptr = 'd0;
rd_ptr = 'd0;
full = 1'b0;
dout = 8'd0;
for (k = 0; k < MEM_DEPTH; k = k + 1)
begin
data[k] = 32'd0;
end
$display("FIFO has %x", MEM_DEPTH);
end
reg [BYTE_WIDTH-1:0] rd_ptr_r;
always @(posedge wr_clk) begin
reg rstD, rstD2;
rd_ptr_r <= rd_ptr;
space <= {rd_ptr_r[BYTE_WIDTH-1:2]} - wr_ptr;
rstD <= rst;
rstD2 <= rstD;
if (rstD2) begin
wr_ptr <= 'd0;
full <= 1'b0;
end else begin
if (wr_ptr != {rd_ptr_r[BYTE_WIDTH-1:2]}) begin
full <= 1'b0;
end
if (wr_en == 1'b1) begin
data[wr_ptr] <= din;
wr_ptr <= wr_ptr + 2'd1;
full <= (wr_ptr + 2'd1) == {rd_ptr_r[BYTE_WIDTH-1:2]};
end
end
end
wire [7:0] q;
always @(posedge rd_clk) begin
reg rstD, rstD2;
rstD <= rst;
rstD2 <= rstD;
if(rd_ce) begin
if (rstD2) begin
rd_ptr <= 'd0;
dout <= 8'd0;
end else if (rd_en) begin
if (~empty) begin
rd_ptr <= rd_ptr + 1'd1;
dout <= q;
end else begin
dout <= 'd0;
end
end
end
end
assign empty = !full & space == 'd0;
// cross the clock domain.
assign q = (rd_ptr[1:0] == 2'b00) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][7:0] :
(rd_ptr[1:0] == 2'b01) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][15:8] :
(rd_ptr[1:0] == 2'b10) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][23:16] : data[{rd_ptr[BYTE_WIDTH-1:2]}][31:24];
endmodule