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/bench
    from Rev 2 to Rev 21
    Reverse comparison

Rev 2 → Rev 21

/rtfSerialTxSim.v
0,0 → 1,69
// ============================================================================
// __
// \\__/ o\ (C) 2015 Robert Finch, Stratford
// \ __ / 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/>.
//
// This core simulates a serial transmitter by outputing a text stream.
// ============================================================================
//
module rtfSerialTxSim(rst,baud16,txd);
input rst;
input baud16;
output txd;
 
reg [9:0] buff;
reg [9:0] buf2;
reg [5:0] cnt;
reg [3:0] bitcnt;
reg [7:0] msg [0:7];
reg [7:0] msgndx;
 
assign txd = buff[9];
 
always @(posedge baud16)
if (rst) begin
cnt <= 6'd0;
buff <= 10'h3FF;
buf2 <= 10'h3ff;
msg[0] = "H";
msg[1] = "i";
msg[2] = "T";
msg[3] = "h";
msg[4] = "e";
msg[5] = "r";
msg[6] = "e";
msg[7] = " ";
msgndx <= 4'd0;
end
else begin
cnt <= cnt + 6'd1;
if (cnt==6'd15) begin
cnt <= 6'd0;
bitcnt <= bitcnt + 4'd1;
if (bitcnt==4'd9) begin
bitcnt <= 4'd0;
buff <= buf2;
msgndx <= msgndx + 8'd1;
buf2 <= {1'b0,msg[msgndx],^msg[msgndx]};
end
else
buff <= {buff[8:0],1'b1};
end
end
 
endmodule
/Thor_tb.v
5,6 → 5,7
reg clk;
reg nmi;
reg p100Hz;
reg p1000Hz;
wire [2:0] cti;
wire cpu_clk;
wire cyc;
13,9 → 14,11
wire [7:0] sel;
wire br_ack;
wire [31:0] adr;
wire [DBW-1:0] br_dato;
wire [DBW+6:0] br_dato;
wire scr_ack;
wire [63:0] scr_dato;
reg [31:0] rammem [0:1048575];
wire err1,err2;
 
wire cpu_ack;
wire [DBW-1:0] cpu_dati;
23,7 → 26,11
wire pic_ack,irq;
wire [31:0] pic_dato;
wire [7:0] vecno;
 
wire baud16;
wire uart_rxd;
wire uart_ack;
wire uart_irq;
wire [7:0] uart_dato;
wire LEDS_ack;
 
initial begin
31,20 → 38,36
#0 clk = 1'b0;
#0 nmi = 1'b0;
#0 p100Hz = 1'b0;
#0 p1000Hz = 1'b1;
#10 rst = 1'b1;
#50 rst = 1'b0;
#19550 nmi = 1'b1;
#20800 nmi = 1'b1;
#20 nmi = 1'b0;
end
 
always #5 clk = ~clk;
always #10000 p100Hz = ~p100Hz;
always #3000 p1000Hz = ~p1000Hz;
 
wire ram_cs = cyc && stb && adr[31:28]==4'd0 && adr[31:14]!= 18'h0000;
wire [31:0] ramo = ram_cs ? rammem[adr[21:2]] : 32'd0;
always @(posedge clk)
if (ram_cs & we) begin
if (sel[0]) rammem[adr[21:2]][7:0] <= cpu_dato[7:0];
if (sel[1]) rammem[adr[21:2]][15:8] <= cpu_dato[15:8];
if (sel[2]) rammem[adr[21:2]][23:16] <= cpu_dato[23:16];
if (sel[3]) rammem[adr[21:2]][31:24] <= cpu_dato[31:24];
end
 
assign LEDS_ack = cyc && stb && adr[31:8]==32'hFFDC06;
always @(posedge clk)
if (LEDS_ack)
$display("LEDS: %b", cpu_dato[7:0]);
 
always @(posedge clk)
if ((err1|err2)&&$time > 11000)
$stop;
 
wire tc1_ack, tc2_ack;
wire kbd_ack;
wire [31:0] tc1_dato, tc2_dato;
57,7 → 80,8
scr_ack |
br_ack |
tc1_ack | tc2_ack |
kbd_ack | pic_ack
kbd_ack | pic_ack |
ram_cs | uart_ack
;
assign cpu_dati =
scr_dato |
64,9 → 88,44
br_dato |
tc1_dato | tc2_dato |
{4{kbd_dato}} |
pic_dato
pic_dato |
ramo |
{4{uart_dato}}
;
 
rtfSerialTxSim ussim1
(
.rst(rst),
.baud16(baud16),
.txd(uart_rxd)
);
 
rtfSimpleUart uuart1
(
// WISHBONE Slave interface
.rst_i(rst), // reset
.clk_i(clk), // eg 100.7MHz
.cyc_i(cyc), // cycle valid
.stb_i(stb), // strobe
.we_i(we), // 1 = write
.adr_i(adr), // register address
.dat_i(cpu_dato[7:0]), // data input bus
.dat_o(uart_dato), // data output bus
.ack_o(uart_ack), // transfer acknowledge
.vol_o(), // volatile register selected
.irq_o(uart_irq), // interrupt request
//----------------
.cts_ni(1'b0), // clear to send - active low - (flow control)
.rts_no(), // request to send - active low - (flow control)
.dsr_ni(1'b0), // data set ready - active low
.dcd_ni(1'b0), // data carrier detect - active low
.dtr_no(), // data terminal ready - active low
.rxd_i(uart_rxd), // serial data in
.txd_o(), // serial data out
.data_present_o(),
.baud16_clk(baud16)
);
 
Ps2Keyboard_sim ukbd
(
.rst_i(rst),
105,7 → 164,7
.rgbOut()
);
 
rtfTextController3 #(.num(1), .pTextAddress(32'hFFD10000)) tc2
rtfTextController3 #(.num(1), .pTextAddress(32'hFFD10000), .pRegAddress(32'hFFDA0040)) tc2
(
.rst_i(rst),
.clk_i(cpu_clk),
151,7 → 210,9
.ack_o(br_ack),
.adr_i(adr),
.dat_o(br_dato),
.perr()
.perr(),
.err1(err1),
.err2(err2)
);
 
wire nmio;
167,13 → 228,13
.dat_i(cpu_dato),
.dat_o(pic_dato),
.vol_o(), // volatile register selected
.i1(),
.i1(p1000Hz),
.i2(p100Hz),
.i3(),
.i4(),
.i5(),
.i6(),
.i7(),
.i7(uart_irq),
.i8(),
.i9(),
.i10(),
/bootrom.v
21,7 → 21,7
//
// ============================================================================
//
module bootrom(rst_i, clk_i, cti_i, cyc_i, stb_i, ack_o, adr_i, dat_o, perr);
module bootrom(rst_i, clk_i, cti_i, cyc_i, stb_i, ack_o, adr_i, dat_o, perr, err1, err2);
parameter DBW=64;
parameter MAGIC1=32'hAAAAAAAA;
parameter MAGIC2=32'h55555555;
32,10 → 32,11
input stb_i;
output ack_o;
input [31:0] adr_i;
output [DBW-1:0] dat_o;
reg [DBW-1:0] dat_o;
output [DBW+6:0] dat_o;
reg [DBW+6:0] dat_o;
output perr;
reg perr;
output err1;
output err2;
 
wire ne_cs;
wire cs;
50,22 → 51,22
ack2 <= ack1 & cs;
ack3 <= ack2 & cs;
end
assign cs = cyc_i && stb_i && adr_i[31:16]==16'hFFFF;
assign cs = cyc_i && stb_i && adr_i[31:20]==12'hFFF;
assign ack_o = cs & ack0;
 
reg [DBW:0] rommem0 [0:8191];
reg [DBW:0] rommem1 [0:8191];
reg [DBW:0] rommem2 [0:8191];
reg [38:0] rommem0 [0:25599];
//reg [DBW-1:0] rommem1 [0:7167];
//reg [DBW-1:0] rommem2 [0:7167];
initial begin
if (DBW==32) begin
`include "..\..\software\A64\bin\boot.ve0"
`include "..\..\software\A64\bin\boot.ve1"
`include "..\..\software\A64\bin\boot.ve2"
`include "..\..\software\source\boot.ve0"
//`include "..\..\software\A64\bin\boot.ve1"
//`include "..\..\software\A64\bin\boot.ve2"
end
else begin
`include "..\..\software\a64\bin\boot.ve0"
`include "..\..\software\A64\bin\boot.ve1"
`include "..\..\software\A64\bin\boot.ve2"
`include "..\..\software\source\boot.ve0"
//`include "..\..\software\A64\bin\boot.ve1"
//`include "..\..\software\A64\bin\boot.ve2"
end
end
 
92,23 → 93,37
else
radr <= pe_cs ? adr_i[14:3] : ctr;
 
wire [31:0] d0 = rommem0[radr][DBW-1:0];
wire [31:0] d1 = rommem1[radr][DBW-1:0]^MAGIC1;
wire [31:0] d2 = rommem2[radr][DBW-1:0]^MAGIC2;
wire [31:0] d4 = (d0&d1)|(d0&d2)|(d1&d2);
wire [38:0] d0 = rommem0[radr];
//wire [31:0] d1 = rommem1[radr][DBW-1:0]^MAGIC1;
//wire [31:0] d2 = rommem2[radr][DBW-1:0]^MAGIC2;
wire [31:0] d4;//(d0&d1)|(d0&d2)|(d1&d2);
 
//ECC ecc1(d0,d4);
ecc_0 uecc1 (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(d0[31:0]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(d4), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({d0[37:32],d0[38]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(err1), // output wire ecc_sbit_err
.ecc_dbit_err(err2) // output wire ecc_dbit_err
);
 
 
always @(posedge clk_i)
if (cs) begin
dat_o <= d4;
dat_o <= {d0[38:32],d4};
$display("br read: %h %h", radr,d4);
end
else
dat_o <= {DBW{1'b0}};
dat_o <= {DBW+6{1'b0}};
 
/*
always @(posedge clk_i)
if (cs)
perr <= ^rommem0[radr][DBW-1:0]!=rommem0[radr][DBW];
else
perr <= 1'd0;
*/
assign perr = 1'b0;
 
endmodule
/readme.txt
0,0 → 1,3
Missing modules for the test-bench can be found under the
rtfTextController project at OpenCores Video projects.
rtfSimpleUart project at OpenCores under Communications projects.
/rtfTextController3.v
0,0 → 1,652
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2006-2014 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// rtfTextController3.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
//
// 00 - nnnnnnnn number of columns (horizontal displayed number of characters)
// 01 - nnnnnnnn number of rows (vertical displayed number of characters)
// 02 - n nnnnnnnn window left (horizontal sync position - reference for left edge of displayed)
// 03 - n nnnnnnnn window top (vertical sync position - reference for the top edge of displayed)
// 04 - ---nnnnn maximum scan line (char ROM max value is 7)
// 05 - hhhhwwww pixel size, hhhh=height,wwww=width
// 07 - n nnnnnnnn color code for transparent background
// 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
// 09 - ----nnnnn cursor end
// 10 - aaaaaaaa aaaaaaaaa start address (index into display memory)
// 11 - aaaaaaaa aaaaaaaaa cursor position
// 12 - aaaaaaaa aaaaaaaaa light pen position
//--------------------------------------------------------------------
//
// ============================================================================
 
module rtfTextController3(
rst_i, clk_i,
cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o,
lp, curpos,
vclk, hsync, vsync, blank, border, rgbIn, rgbOut
);
parameter num = 4'd1;
parameter COLS = 12'd84;
parameter ROWS = 12'd31;
parameter pTextAddress = 32'hFFD00000;
parameter pBitmapAddress = 32'hFFD20000;
parameter pRegAddress = 32'hFFDA0000;
 
// Syscon
input rst_i; // reset
input clk_i; // clock
 
// Slave signals
input cyc_i; // cycle valid
input stb_i; // data strobe
output ack_o; // transfer acknowledge
input we_i; // write
input [31: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 [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_text = cyc_i && stb_i && (adr_i[31:16]==pTextAddress[31:16]);
wire cs_rom = cyc_i && stb_i && (adr_i[31:16]==pBitmapAddress[31:16]);
wire cs_reg = cyc_i && stb_i && (adr_i[31: 6]==pRegAddress[31:6]);
wire cs_any = cs_text|cs_rom|cs_reg;
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;
 
// text screen RAM
syncRam4kx9_1rw1r textRam0
(
.wclk(clk_i),
.wadr(adr_i[13:2]),
.i(dat_i[8:0]),
.wo(tdat_o[8:0]),
.wce(cs_text),
.we(we_i),
.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(adr_i[13:2]),
.i(dat_i[18:10]),
.wo(tdat_o[18:10]),
.wce(cs_text),
.we(we_i),
.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(adr_i[13:2]),
.i(dat_i[27:19]),
.wo(tdat_o[27:19]),
.wce(cs_text),
.we(we_i),
.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(adr_i[13:2]),
.i(dat_i),
.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 ? (we_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)
if (cs_reg) begin
case(adr_i[5:2])
4'd0: rego <= numCols;
4'd1: rego <= numRows;
4'd11: rego <= cursorPos;
4'd12: rego <= penAddr;
default: rego <= 16'h0000;
endcase
end
else
rego <= 16'h0000;
 
 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Register write port
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
reg interlace;
always @(posedge clk_i)
if (rst_i) begin
// 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'h66;//12'd86;
pixelWidth <= 4'd1; // 680 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 & we_i) begin // register write ?
$display("TC Write: r%d=%h", adr_i[5:2], dat_i);
case(adr_i[5:2])
4'd00: begin
numCols <= dat_i[15:0]; // horizontal displayed
charOutDelay <= dat_i[31:16];
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'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(nvp),
.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)
);
 
 
// 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,pix})
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;
default: rgbOut <= rgbIn;
endcase
end
 
endmodule
 

powered by: WebSVN 2.1.0

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