mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-05-05 15:54:29 +00:00
IO redirection improvements
This commit is contained in:
@@ -625,5 +625,5 @@ set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LE
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_LOWORD=15587" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_CRC_HIWORD=44938" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=M9K" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_FILE db/stp1_auto_stripped.stp
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_global_assignment -name SLD_FILE db/stp1_auto_stripped.stp
|
||||
Binary file not shown.
@@ -23,21 +23,49 @@ module acia (
|
||||
output [7:0] ikbd_data_out
|
||||
);
|
||||
|
||||
localparam FIFO_ADDR_BITS = 4;
|
||||
localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS);
|
||||
// --- ikbd output fifo ---
|
||||
// filled by the CPU when writing to the acia data register
|
||||
// emptied by the io controller when reading via SPI
|
||||
io_fifo ikbd_out_fifo (
|
||||
.reset (reset),
|
||||
|
||||
// input FIFO to store ikbd bytes received from IO controller
|
||||
reg [7:0] fifoIn [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePin, readPin;
|
||||
.in_clk (!clk), // latch incoming data on negedge
|
||||
.in (din),
|
||||
.in_strobe (1'b0),
|
||||
.in_enable (sel && ~ds && ~rw && (addr == 2'd1)),
|
||||
|
||||
// output FIFO to store ikbd bytes to be sent to IO controller
|
||||
reg [7:0] fifoOut [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePout, readPout;
|
||||
.out_clk (clk),
|
||||
.out (ikbd_data_out),
|
||||
.out_strobe (ikbd_strobe_out),
|
||||
.out_enable (1'b0),
|
||||
|
||||
.data_available (ikbd_data_out_available)
|
||||
);
|
||||
|
||||
// --- ikbd input fifo ---
|
||||
// filled by the io controller when writing via SPI
|
||||
// emptied by the CPU when reading the acia data register
|
||||
io_fifo ikbd_in_fifo (
|
||||
.reset (reset || (ikbd_cr[1:0] == 2'b11)),
|
||||
|
||||
.in_clk (!clk), // latch incoming data on negedge
|
||||
.in (ikbd_data_in),
|
||||
.in_strobe (ikbd_strobe_in),
|
||||
.in_enable (1'b0),
|
||||
|
||||
.out_clk (!clk),
|
||||
.out (ikbd_rx_data),
|
||||
.out_strobe (1'b0),
|
||||
.out_enable (ikbd_cpu_data_read && ikbd_rx_data_available),
|
||||
|
||||
.data_available (ikbd_rx_data_available)
|
||||
);
|
||||
|
||||
// timer to let bytes arrive at a reasonable speed
|
||||
reg [13:0] readTimer;
|
||||
|
||||
reg ikbd_strobe_inD, ikbd_strobe_inD2;
|
||||
// delay the cpu read to be able to do things afterwards like e.g. incrementing
|
||||
// the fifo pointers
|
||||
reg ikbd_cpu_data_read;
|
||||
reg midi_cpu_data_read;
|
||||
|
||||
@@ -55,9 +83,6 @@ always @(negedge clk) begin
|
||||
if(readTimer > 0)
|
||||
readTimer <= readTimer - 14'd1;
|
||||
|
||||
ikbd_strobe_inD <= ikbd_strobe_in;
|
||||
ikbd_strobe_inD2 <= ikbd_strobe_inD;
|
||||
|
||||
// read on ikbd data register
|
||||
ikbd_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 2'd1)) begin
|
||||
@@ -70,28 +95,8 @@ always @(negedge clk) begin
|
||||
if(sel && ~ds && rw && (addr == 2'd3))
|
||||
midi_cpu_data_read <= 1'b1;
|
||||
|
||||
if(reset) begin
|
||||
// reset read and write counters
|
||||
readPin <= 4'd0;
|
||||
writePin <= 4'd0;
|
||||
end else begin
|
||||
|
||||
// ikbd acia master reset
|
||||
if(ikbd_cr[1:0] == 2'b11) begin
|
||||
readPin <= 4'd0;
|
||||
writePin <= 4'd0;
|
||||
end
|
||||
|
||||
// store bytes received from IO controller via SPI
|
||||
if(ikbd_strobe_inD && !ikbd_strobe_inD2) begin
|
||||
// store data in fifo
|
||||
fifoIn[writePin] <= ikbd_data_in;
|
||||
writePin <= writePin + 4'd1;
|
||||
end
|
||||
|
||||
if(!reset) begin
|
||||
if(ikbd_cpu_data_read && ikbd_rx_data_available) begin
|
||||
readPin <= readPin + 4'd1;
|
||||
|
||||
// Some programs (e.g. bolo) need a pause between two ikbd bytes.
|
||||
// The ikbd runs at 7812.5 bit/s 1 start + 8 data + 1 stop bit.
|
||||
// One byte is 1/718.25 seconds. A pause of ~1ms is thus required
|
||||
@@ -103,31 +108,20 @@ end
|
||||
|
||||
// ------------------ cpu interface --------------------
|
||||
|
||||
wire ikbd_irq = ikbd_cr[7] && ikbd_rx_data_available; // rx irq
|
||||
wire [7:0] ikbd_rx_data;
|
||||
wire ikbd_rx_data_available;
|
||||
|
||||
wire [7:0] ikbd_rx_data = ikbd_rx_data_available?fifoIn[readPin]:fifoIn[readPin-4'd1];
|
||||
|
||||
wire ikbd_rx_data_available = (readPin != writePin) && (readTimer == 0);
|
||||
wire ikbd_irq = ikbd_cr[7] && cpu_ikbd_rx_data_available; // rx irq
|
||||
|
||||
// the cpu is only being told that data is available if the timer has run down. This
|
||||
// to prevent the CPU from being flooded with data at more then 7812.5bit/s
|
||||
wire cpu_ikbd_rx_data_available = ikbd_rx_data_available && (readTimer == 0);
|
||||
|
||||
// in a real ST the irqs are active low open collector outputs and are simply wired
|
||||
// tegether ("wired or")
|
||||
assign irq = ikbd_irq || midi_irq;
|
||||
|
||||
assign ikbd_data_out_available = (readPout != writePout);
|
||||
assign ikbd_data_out = fifoOut[readPout];
|
||||
|
||||
// ---------------- send acia data to io controller ------------
|
||||
reg ikbd_strobe_outD, ikbd_strobe_outD2;
|
||||
always @(posedge clk) begin
|
||||
ikbd_strobe_outD <= ikbd_strobe_out;
|
||||
ikbd_strobe_outD2 <= ikbd_strobe_outD;
|
||||
|
||||
if(reset)
|
||||
readPout <= 4'd0;
|
||||
else
|
||||
if(ikbd_strobe_outD && !ikbd_strobe_outD2)
|
||||
readPout <= readPout + 4'd1;
|
||||
end
|
||||
|
||||
always @(sel, ds, rw, addr, ikbd_rx_data_available, ikbd_rx_data, ikbd_irq,
|
||||
midi_rx_data, midi_rx_data_available, midi_tx_empty, midi_irq) begin
|
||||
@@ -135,7 +129,7 @@ always @(sel, ds, rw, addr, ikbd_rx_data_available, ikbd_rx_data, ikbd_irq,
|
||||
|
||||
if(sel && ~ds && rw) begin
|
||||
// keyboard acia read
|
||||
if(addr == 2'd0) dout = { ikbd_irq, 6'b000001, ikbd_rx_data_available };
|
||||
if(addr == 2'd0) dout = { ikbd_irq, 6'b000001, cpu_ikbd_rx_data_available};
|
||||
if(addr == 2'd1) dout = ikbd_rx_data;
|
||||
|
||||
// midi acia read
|
||||
@@ -254,7 +248,6 @@ always @(negedge clk) begin
|
||||
midi_reg_data_cnt <= 8'd0;
|
||||
midi_reg_ctrl_cnt <= 8'd0;
|
||||
|
||||
writePout <= 4'd0;
|
||||
midi_tx_cnt <= 8'd0;
|
||||
midi_tx_data_valid <= 1'b0;
|
||||
end else begin
|
||||
@@ -264,12 +257,9 @@ always @(negedge clk) begin
|
||||
if(addr == 2'd0)
|
||||
ikbd_cr <= din;
|
||||
|
||||
// keyboard acia data register writes into buffer
|
||||
if(addr == 2'd1) begin
|
||||
fifoOut[writePout] <= din;
|
||||
writePout <= writePout + 4'd1;
|
||||
end
|
||||
|
||||
// keyboard acia data register omn addr 2 writes happen in the fifo
|
||||
// ...
|
||||
|
||||
// write to midi control register
|
||||
if(addr == 2'd2) begin
|
||||
midi_cr <= din;
|
||||
|
||||
@@ -21,6 +21,7 @@ module mfp (
|
||||
// serial rs223 connection from io controller
|
||||
input serial_strobe_in,
|
||||
input [7:0] serial_data_in,
|
||||
output serial_data_in_full,
|
||||
|
||||
// inputs
|
||||
input clk_ext, // external 2.457MHz
|
||||
@@ -28,72 +29,57 @@ module mfp (
|
||||
input [7:0] i // input port
|
||||
);
|
||||
|
||||
localparam FIFO_ADDR_BITS = 4;
|
||||
localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS);
|
||||
// --- mfp output fifo ---
|
||||
// filled by the CPU when writing to the mfp uart data register
|
||||
// emptied by the io controller when reading via SPI
|
||||
io_fifo mfp_out_fifo (
|
||||
.reset (reset),
|
||||
|
||||
// fifo for data from mfp to io controller
|
||||
reg [7:0] fifoOut [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePout, readPout;
|
||||
.in_clk (!clk), // latch incoming data on negedge
|
||||
.in (din),
|
||||
.in_strobe (1'b0),
|
||||
.in_enable (sel && ~ds && ~rw && (addr == 5'h17)),
|
||||
|
||||
// fifo for data from io-controller to mfp
|
||||
reg [7:0] fifoIn [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePin, readPin;
|
||||
.out_clk (clk),
|
||||
.out (serial_data_out),
|
||||
.out_strobe (serial_strobe_out),
|
||||
.out_enable (1'b0),
|
||||
|
||||
assign serial_data_out_available = (readPout != writePout);
|
||||
assign serial_data_out = fifoOut[readPout];
|
||||
.full (serial_data_out_fifo_full),
|
||||
.data_available (serial_data_out_available)
|
||||
);
|
||||
|
||||
wire serial_data_in_available = (readPin != writePin) /* synthesis keep */;
|
||||
wire [7:0] serial_data_in_cpu = serial_data_in_available?fifoIn[readPin]:fifoIn[readPin-4'd1];
|
||||
// --- mfp input fifo ---
|
||||
// filled by the io controller when writing via SPI
|
||||
// emptied by CPU when reading the mfp uart data register
|
||||
io_fifo mfp_in_fifo (
|
||||
.reset (reset),
|
||||
|
||||
// signal "fifo is full" via uart config bit
|
||||
wire serial_data_out_fifo_full = (readPout === (writePout + 4'd1));
|
||||
.in_clk (!clk), // latch incoming data on negedge
|
||||
.in (serial_data_in),
|
||||
.in_strobe (serial_strobe_in),
|
||||
.in_enable (1'b0),
|
||||
|
||||
.out_clk (!clk),
|
||||
.out (serial_data_in_cpu),
|
||||
.out_strobe (1'b0),
|
||||
.out_enable (serial_cpu_data_read && serial_data_in_available),
|
||||
|
||||
.full (serial_data_in_full),
|
||||
.data_available (serial_data_in_available)
|
||||
);
|
||||
|
||||
// ---------------- mfp uart data to/from io controller ------------
|
||||
reg serial_strobe_inD, serial_strobe_inD2;
|
||||
reg serial_cpu_data_read;
|
||||
wire serial_data_in_available;
|
||||
wire [7:0] serial_data_in_cpu;
|
||||
|
||||
always @(negedge clk) begin
|
||||
serial_strobe_inD <= serial_strobe_in;
|
||||
serial_strobe_inD2 <= serial_strobe_inD;
|
||||
|
||||
// read on uart data register
|
||||
serial_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 5'h17))
|
||||
serial_cpu_data_read <= 1'b1;
|
||||
|
||||
if(reset) begin
|
||||
// reset read and write counters
|
||||
readPin <= 4'd0;
|
||||
writePin <= 4'd0;
|
||||
end else begin
|
||||
// store bytes received from IO controller via SPI
|
||||
if(serial_strobe_inD && !serial_strobe_inD2) begin
|
||||
// store data in fifo
|
||||
fifoIn[writePin] <= serial_data_in;
|
||||
writePin <= writePin + 4'd1;
|
||||
end
|
||||
|
||||
// advance read pointer on every cpu read
|
||||
if(serial_cpu_data_read && serial_data_in_available)
|
||||
readPin <= readPin + 4'd1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg serial_strobe_outD, serial_strobe_outD2;
|
||||
always @(posedge clk) begin
|
||||
serial_strobe_outD <= serial_strobe_out;
|
||||
serial_strobe_outD2 <= serial_strobe_outD;
|
||||
|
||||
if(reset)
|
||||
readPout <= 4'd0;
|
||||
else
|
||||
if(serial_strobe_outD && !serial_strobe_outD2)
|
||||
readPout <= readPout + 4'd1;
|
||||
end
|
||||
|
||||
// timer to let bytes arrive at a reasonable speed
|
||||
reg [13:0] readTimer;
|
||||
|
||||
wire write = sel && ~ds && ~rw;
|
||||
|
||||
@@ -303,7 +289,6 @@ always @(negedge clk) begin
|
||||
if(reset) begin
|
||||
ipr <= 16'h0000; ier <= 16'h0000;
|
||||
imr <= 16'h0000; isr <= 16'h0000;
|
||||
writePout <= 0;
|
||||
end else begin
|
||||
|
||||
// ack pending irqs and set isr if enabled
|
||||
@@ -361,10 +346,7 @@ always @(negedge clk) begin
|
||||
if(addr == 5'h15) uart_rx_ctrl <= din[1:0];
|
||||
if(addr == 5'h16) uart_tx_ctrl <= din[3:0];
|
||||
|
||||
if(addr == 5'h17) begin
|
||||
fifoOut[writePout] <= din;
|
||||
writePout <= writePout + 4'd1;
|
||||
end
|
||||
// write to addr == 5'h17 is handled by the output fifo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -289,8 +289,8 @@ wire mfp_io7 = system_ctrl[8] ^ (ste?ste_dma_snd_xsirq:1'b0);
|
||||
|
||||
// input 0 is busy from printer which is pulled up when the printer cannot accept further data
|
||||
// inputs 1,2 and 6 are inputs from serial which have pullups before an inverter
|
||||
wire [7:0] mfp_gpio_in = {mfp_io7, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 2'b00, parallal_fifo_full};
|
||||
wire [1:0] mfp_timer_in = {st_de, ste?ste_dma_snd_xsirq_delayed:parallal_fifo_full};
|
||||
wire [7:0] mfp_gpio_in = {mfp_io7, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 2'b00, parallel_fifo_full};
|
||||
wire [1:0] mfp_timer_in = {st_de, ste?ste_dma_snd_xsirq_delayed:parallel_fifo_full};
|
||||
|
||||
mfp mfp (
|
||||
// cpu register interface
|
||||
@@ -346,6 +346,7 @@ wire [23:1] blitter_master_addr;
|
||||
wire blitter_master_write;
|
||||
wire blitter_master_read;
|
||||
wire blitter_irq;
|
||||
wire blitter_br;
|
||||
wire [15:0] blitter_master_data_out;
|
||||
|
||||
blitter blitter (
|
||||
@@ -458,46 +459,26 @@ sigma_delta_dac sigma_delta_dac_r (
|
||||
|
||||
//// ym2149 sound chip ////
|
||||
|
||||
wire parallel_fifo_full;
|
||||
|
||||
// ------ fifo to store printer data coming from psg ---------
|
||||
localparam FIFO_ADDR_BITS = 4;
|
||||
localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS);
|
||||
reg [7:0] fifoOut [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePout, readPout;
|
||||
io_fifo #(.DEPTH(4)) parallel_out_fifo (
|
||||
.reset (reset),
|
||||
|
||||
wire parallal_fifo_full = (readPout === (writePout + 4'd1));
|
||||
assign parallel_data_out_available = (readPout != writePout);
|
||||
assign parallel_data_out = fifoOut[readPout];
|
||||
.in_clk (clk_8),
|
||||
.in (port_b_out),
|
||||
.in_strobe (port_a_out[5]),
|
||||
.in_enable (1'b0),
|
||||
|
||||
// parallel strobe signal
|
||||
reg parallel_strobeD, parallel_strobeD2;
|
||||
// strobe signal by io controller when reading from parallel fifo
|
||||
reg parallel_strobe_outD, parallel_strobe_outD2;
|
||||
.out_clk (clk_8),
|
||||
.out (parallel_data_out),
|
||||
.out_strobe (parallel_strobe_out),
|
||||
.out_enable (1'b0),
|
||||
|
||||
always @(posedge clk_8) begin
|
||||
// printer strobe generated by core/ST using the PSG
|
||||
parallel_strobeD <= port_a_out[5];
|
||||
parallel_strobeD2 <= parallel_strobeD;
|
||||
.full (parallel_fifo_full),
|
||||
.data_available (parallel_data_out_available)
|
||||
);
|
||||
|
||||
// fifo read strobe generated by io controller
|
||||
parallel_strobe_outD <= parallel_strobe_out;
|
||||
parallel_strobe_outD2 <= parallel_strobe_outD;
|
||||
|
||||
if(reset) begin
|
||||
readPout <= 4'd0;
|
||||
writePout <= 4'd0;
|
||||
end else begin
|
||||
// rising edge on fifo read strobe from io controller
|
||||
if(parallel_strobe_outD && !parallel_strobe_outD2)
|
||||
readPout <= readPout + 4'd1;
|
||||
|
||||
// rising edge on strobe signal coming from psg
|
||||
if(parallel_strobeD && !parallel_strobeD2) begin
|
||||
fifoOut[writePout] <= port_b_out;
|
||||
writePout <= writePout + 4'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [1:0] sclk;
|
||||
always @ (posedge clk_8)
|
||||
sclk <= sclk + 2'd1;
|
||||
|
||||
Reference in New Issue
Block a user