-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvga_text_avl_interface.sv.bak
133 lines (107 loc) · 4.27 KB
/
vga_text_avl_interface.sv.bak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/************************************************************************
Avalon-MM Interface VGA Text mode display
Register Map:
0x000-0x0257 : VRAM, 80x30 (2400 byte, 600 word) raster order (first column then row)
0x258 : control register
VRAM Format:
X->
[ 31 30-24][ 23 22-16][ 15 14-8 ][ 7 6-0 ]
[IV3][CODE3][IV2][CODE2][IV1][CODE1][IV0][CODE0]
IVn = Draw inverse glyph
CODEn = Glyph code from IBM codepage 437
Control Register Format:
[[31-25][24-21][20-17][16-13][ 12-9][ 8-5 ][ 4-1 ][ 0 ]
[[RSVD ][FGD_R][FGD_G][FGD_B][BKG_R][BKG_G][BKG_B][RESERVED]
VSYNC signal = bit which flips on every Vsync (time for new frame), used to synchronize software
BKG_R/G/B = Background color, flipped with foreground when IVn bit is set
FGD_R/G/B = Foreground color, flipped with background when Inv bit is set
************************************************************************/
`define NUM_REGS 601 //80*30 characters / 4 characters per register
`define CTRL_REG 600 //index of control register
module vga_text_avl_interface (
// Avalon Clock Input, note this clock is also used for VGA, so this must be 50Mhz
// We can put a clock divider here in the future to make this IP more generalizable
input logic CLK,
// Avalon Reset Input
input logic RESET,
// Avalon-MM Slave Signals
input logic AVL_READ, // Avalon-MM Read
input logic AVL_WRITE, // Avalon-MM Write
input logic AVL_CS, // Avalon-MM Chip Select
input logic [3:0] AVL_BYTE_EN, // Avalon-MM Byte Enable
input logic [9:0] AVL_ADDR, // Avalon-MM Address
input logic [31:0] AVL_WRITEDATA, // Avalon-MM Write Data
output logic [31:0] AVL_READDATA, // Avalon-MM Read Data
// Exported Conduit (mapped to VGA port - make sure you export in Platform Designer)
output logic [3:0] red, green, blue, // VGA color channels (mapped to output pins in top-level)
output logic hs, vs // VGA HS/VS
);
//logic [31:0] LOCAL_REG [`NUM_REGS]; // Registers
//// Read and write from AVL interface to register block, note that READ waitstate = 1, so this should be in always_ff
//// implement control register
//always_ff@(posedge CLK)
//begin
//if(AVL_WRITE && AVL_CS)
//begin
// if(AVL_ADDR == `CTRL_REG)
// LOCAL_REG[AVL_ADDR][31:0] <= AVL_WRITEDATA[31:0];
// if(AVL_BYTE_EN[0])
// LOCAL_REG[AVL_ADDR][7:0] <= AVL_WRITEDATA[7:0];
// if(AVL_BYTE_EN[1])
// LOCAL_REG[AVL_ADDR][15:8] <= AVL_WRITEDATA[15:8];
// if(AVL_BYTE_EN[2])
// LOCAL_REG[AVL_ADDR][23:16] <= AVL_WRITEDATA[23:16];
// if(AVL_BYTE_EN[3])
// LOCAL_REG[AVL_ADDR][31:24] <= AVL_WRITEDATA[31:24];
//end
//else if(AVL_READ && AVL_CS)
// AVL_READDATA[31:0] <= LOCAL_REG[AVL_ADDR][31:0];
//
//else if(RESET)
// begin
// for(int i = 0; i<`NUM_REGS; i++)
// begin
// LOCAL_REG[i] <= 32'h00000000;
// end
// end
//end
//put other local variables here
logic [10:0] Font_Rom_ADDR;
logic [7:0] Font_Rom_DATA;
logic [9:0] DrawX, DrawY, Word_ADDR;
logic [11:0] Byte_ADDR;
logic [7:0] CodeN;
logic [31:0] LOCAL_REG;
logic blank;
//logic [1:0] Byte_INDEX;
//logic CurrInv;
//Declare submodules..e.g. VGA controller, ROMS, etc
ram0 ram1(.byteena_a(AVL_BYTE_EN), .clock(CLK), .data(AVL_WRITEDATA), .rdaddress(Word_ADDR), .rden(AVL_READ && AVL_CS),
.wraddress(AVL_ADDR), .wren(AVL_WRITE && AVL_CS), .q(LOCAL_REG));
font_rom FR(.addr(Font_Rom_ADDR), .data(Font_Rom_DATA));
vga_controller VGA_C(.Clk(CLK), .Reset(RESET), .hs(hs), .vs(vs), .DrawX(DrawX), .DrawY(DrawY), .blank(blank));
// Give the Control Register Values
color_mapper CM(.DrawX(~DrawX[2:0]), .Font_Rom_DATA(Font_Rom_DATA), .blank(blank),
.FGD_R(4'hF), .FGD_G(4'hF),
.FGD_B(4'hF), .BKG_R(4'h0),
.BKG_G(4'h0), .BKG_B(4'h0),
.INV(CodeN[7]), .Red(red), .Green(green), .Blue(blue));
//handle drawing (may either be combinational or sequential - or both).
// Handle reading the Codes from the Local regs
always_comb
begin
Byte_ADDR[11:0] = DrawX[9:3] + DrawY[9:4]*7'd80;
Word_ADDR = Byte_ADDR[11:2];
if(Byte_ADDR[1:0] == 2'b00)
CodeN[7:0] = LOCAL_REG[7:0];
else if(Byte_ADDR[1:0] == 2'b01)
CodeN[7:0] = LOCAL_REG[15:8];
else if(Byte_ADDR[1:0] == 2'b10)
CodeN[7:0] = LOCAL_REG[23:16];
else if(Byte_ADDR[1:0] == 2'b11)
CodeN[7:0] = LOCAL_REG[31:24];
else
CodeN[7:0] = 8'h00;
Font_Rom_ADDR = {{CodeN[6:0]}, {DrawY[3:0]}};
end
endmodule