Created
January 27, 2016 08:48
-
-
Save mntmn/69aa76ea1950def9ae2f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
////////////////////////////////////////////////////////////////////////////////// | |
// Company: MNT Media & Technology UG | |
// Engineer: Lukas F. Hartmann | |
// | |
// Create Date: 01:44:12 05/03/2015 | |
// Design Name: | |
// Module Name: vga | |
// Project Name: | |
// Target Devices: | |
// Tool versions: | |
// Description: | |
// | |
// Dependencies: | |
// | |
// Revision: | |
// Revision 0.01 - File Created | |
// Additional Comments: | |
// | |
////////////////////////////////////////////////////////////////////////////////// | |
module vga( | |
output vsync, | |
output hsync, | |
output reg vgaclock, | |
output reg[15:0] rgb, | |
output reg LED1, | |
input CLK_IN1, | |
output SDRAM_CLK, | |
output SDRAM_CKE, | |
output SDRAM_CS, | |
output SDRAM_nRAS, | |
output SDRAM_nCAS, | |
output SDRAM_nWE, | |
output [1:0] SDRAM_DQM, | |
output [12:0] SDRAM_ADDR, | |
output [1:0] SDRAM_BA, | |
inout [15:0] SDRAM_DATA, | |
inout [15:0] z_host, | |
output reg sel_data, | |
output reg sel_addr, | |
input bcfgin, | |
input bas, | |
input e7m, | |
input buds, | |
output bcfgout, | |
output doe, | |
output bslaven, | |
input read, | |
output aux1, | |
output aux2, | |
output aux3 | |
); | |
assign aux1 = 1; | |
assign aux2 = 1; | |
assign aux3 = 1; | |
wire sdram_reset; | |
reg ram_enable; | |
reg [18:0] ram_addr; | |
wire [31:0] ram_data_out; | |
wire data_out_ready; | |
reg [31:0] ram_data_in; | |
reg ram_write; | |
reg [3:0] ram_byte_enable; | |
DCM instance_name( | |
.CLK_IN1(CLK_IN1), | |
.CLK_OUT1(clk), // 100 | |
.CLK_OUT2(ram_clk_gen), // 50 | |
.CLK_OUT3(vga_clk_gen), | |
.CLK_OUT4(z_sample_clk)); | |
SDRAM_Controller_v sdram( | |
.clk(sdram_clk), | |
.reset(sdram_reset), | |
// command and write port | |
.cmd_ready(cmd_ready), | |
.cmd_enable(ram_enable), | |
.cmd_wr(ram_write), | |
.cmd_byte_enable(ram_byte_enable), | |
.cmd_address(ram_addr), | |
.cmd_data_in(ram_data_in), | |
// Read data port | |
.data_out(ram_data_out), | |
.data_out_ready(data_out_ready), | |
// signals | |
.SDRAM_CLK(SDRAM_CLK), | |
.SDRAM_CKE(SDRAM_CKE), | |
.SDRAM_CS(SDRAM_CS), | |
.SDRAM_RAS(SDRAM_RAS), | |
.SDRAM_CAS(SDRAM_CAS), | |
.SDRAM_WE(SDRAM_WE), | |
.SDRAM_DATA(SDRAM_DATA), | |
.SDRAM_ADDR(SDRAM_ADDR), | |
.SDRAM_DQM(SDRAM_DQM), | |
.SDRAM_BA(SDRAM_BA) | |
); | |
/* | |
reg [7:0] ROM [255:0]; | |
initial | |
begin | |
ROM[0]=128; | |
ROM[255]=125; | |
end*/ | |
assign sdram_reset = 0; | |
assign SDRAM_nRAS = SDRAM_RAS; | |
assign SDRAM_nCAS = SDRAM_CAS; | |
assign SDRAM_nWE = SDRAM_WE; | |
reg [9:0] counter_x; | |
reg [8:0] counter_y; | |
reg [11:0] counter_frame; | |
wire counter_xmaxed = (counter_x==767); | |
reg vga_HS, vga_VS; | |
reg [31:0] ram_data_buffer [639:0]; | |
reg written; | |
reg [7:0] host_addr_buf; | |
reg host_pixel_buf; | |
assign sdram_clk = ram_clk_gen; | |
// 64k space from | |
// 00e80000 - 00e8ffff | |
// http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node02C8.htm | |
localparam Z_UNCONFIGURED=0; | |
localparam Z_CONF_ROM=1; | |
localparam Z_CONF_RAM=2; | |
localparam Z_CONF_DONE=3; | |
reg [3:0] z_state; | |
reg [23:0] z_base_addr; | |
reg [23:0] z_addr; | |
reg [15:0] z_data; | |
reg [23:0] z_addr_buffer; | |
reg [3:0] cycle=0; | |
reg blds; | |
reg [15:0] z_host_wire; | |
reg z_host_write = 0; | |
assign z_host = (z_host_write) ? z_host_wire : 'bzzzz_zzzz_zzzz_zzzz; | |
assign doe = (z_host_write); | |
assign bslaven = !(z_host_write); | |
assign bcfgout = !(z_state == Z_CONF_DONE); | |
reg [3:0] errors=0; | |
// 200mhz = 5ns | |
// 100mhz = 10ns | |
always @(posedge clk) begin | |
// interesting values: 0, 3, 4, 6, 7 | |
// address invalid | |
if (cycle==0) begin | |
LED1 <= 0; | |
if (bas || !read) cycle<=1; | |
sel_data <= 1; | |
sel_addr <= 0; | |
if ((z_addr & 'hff0000) == 'he80000) | |
z_addr_buffer <= z_addr; | |
else | |
z_addr_buffer <= 0; | |
z_host_write <= 0; | |
end | |
else if (cycle==1) begin | |
sel_data <= 1; | |
sel_addr <= 0; | |
if (!bas && read) cycle<=2; | |
if (!read) cycle<=0; | |
end | |
else if (cycle<=6) begin // good: 6 | |
sel_data <= 1; | |
sel_addr <= 0; | |
cycle <= cycle + 1; | |
z_addr[0] <= 0; | |
z_addr[17] <= z_host[7]; | |
z_addr[18] <= z_host[6]; | |
z_addr[19] <= z_host[5]; | |
z_addr[20] <= z_host[4]; | |
z_addr[21] <= z_host[3]; | |
z_addr[22] <= z_host[2]; | |
z_addr[23] <= z_host[1]; | |
blds <= z_host[0]; | |
end | |
else if (cycle<=9) begin // good: 9 | |
// address valid | |
sel_data <= 1; | |
sel_addr <= 1; | |
cycle <= cycle + 1; | |
if (bas) errors[0] <= 1; | |
// sel_addr has no effect if sel_data == 0 | |
// z_host[7:0] is noisy when sel_addr == 1 | |
// sample lower 16 bits of address | |
z_addr[9] <= z_host[15]; | |
z_addr[10] <= z_host[14]; | |
z_addr[11] <= z_host[13]; | |
z_addr[12] <= z_host[12]; | |
z_addr[13] <= z_host[11]; | |
z_addr[14] <= z_host[10]; | |
z_addr[15] <= z_host[9]; | |
z_addr[16] <= z_host[8]; | |
z_addr[1] <= z_host[7]; | |
z_addr[2] <= z_host[6]; | |
z_addr[3] <= z_host[5]; | |
z_addr[4] <= z_host[4]; | |
z_addr[5] <= z_host[3]; | |
z_addr[6] <= z_host[2]; | |
z_addr[7] <= z_host[1]; | |
z_addr[8] <= z_host[0]; | |
end else if (cycle<=12) begin | |
cycle <= cycle + 1; | |
sel_data <= 0; | |
if (!read) errors[2] <= 1; | |
// display our data to the bus | |
if (z_state == Z_UNCONFIGURED) begin | |
z_state <= Z_CONF_ROM; | |
end | |
if (z_state == Z_CONF_ROM || z_state == Z_CONF_DONE) begin | |
if ((z_addr & 'hff0000) == 'he80000) begin | |
LED1 <= 1; | |
case (z_addr & 'h0000ff) | |
'h000000: z_data <= 'b1100_0000_0000_0000; // zorro 2 | |
'h000002: z_data <= 'b0111_0000_0000_0000; // 4mb, not linked | |
'h000004: z_data <= 'b0001_0000_0000_0000; // product number | |
'h000006: z_data <= 'b0111_0000_0000_0000; // (23) | |
'h000008: z_data <= 'b0100_0000_0000_0000; // flags | |
'h00000a: z_data <= 'b0000_0000_0000_0000; // sub size automatic | |
'h00000c: z_data <= 'b0000_0000_0000_0000; // reserved | |
'h00000e: z_data <= 'b0000_0000_0000_0000; // | |
'h000010: z_data <= 'b0110_0000_0000_0000; // manufacturer high byte | |
'h000012: z_data <= 'b1101_0000_0000_0000; // | |
'h000014: z_data <= 'b0110_0000_0000_0000; // manufacturer low byte | |
'h000016: z_data <= 'b1101_0000_0000_0000; | |
'h000018: z_data <= 'b0000_0000_0000_0000; // reserved | |
'h00001a: z_data <= 'b0000_0000_0000_0000; // | |
'h000044: z_state <= Z_CONF_DONE; | |
default: z_data <= 'b0000_0000_0000_0000; | |
endcase | |
z_host_write <= 1; | |
z_host_wire[15] <= z_data[0]; | |
z_host_wire[14] <= z_data[1]; | |
z_host_wire[13] <= z_data[2]; | |
z_host_wire[12] <= z_data[3]; | |
z_host_wire[11] <= z_data[4]; | |
z_host_wire[10] <= z_data[5]; | |
z_host_wire[9] <= z_data[6]; | |
z_host_wire[8] <= z_data[7]; | |
z_host_wire[7] <= z_data[8]; | |
z_host_wire[6] <= z_data[9]; | |
z_host_wire[5] <= z_data[10]; | |
z_host_wire[4] <= z_data[11]; | |
z_host_wire[3] <= z_data[12]; | |
z_host_wire[2] <= z_data[13]; | |
z_host_wire[1] <= z_data[14]; | |
z_host_wire[0] <= z_data[15]; | |
end | |
end // end state checking | |
end | |
else cycle <= 0; | |
end // clk | |
/* | |
assign host_high = C9; | |
reg [9:0] fetch_x; | |
reg fetching; | |
always @(posedge sdram_clk) | |
begin | |
ram_byte_enable <= 'b1111; | |
ram_enable <= 1; | |
if (host_high) | |
high_ram_addr <= host_addr; | |
// TODO: ACK, buffer until overscan/sync porch | |
if (host_latch && cmd_ready) | |
begin | |
//ram_addr <= (counter_frame & 'b111111110000)>>2; | |
ram_addr <= ((high_ram_addr&'b11110000)<<10) | ((high_ram_addr&'b1111)<<4) | ((host_addr&'b11110000)<<6) | (host_addr&'b1111) | (high_bit1<<8) | (high_bit2<<18); //&'b1111111100; | |
// write cycle | |
if (host_pixel == 1) | |
begin | |
ram_data_in <= 'hffffffff; | |
ram_write <= 1; | |
ram_enable <= 1; | |
written <= 1; | |
end | |
else | |
begin | |
ram_data_in <= 'hf0000000; | |
ram_write <= 1; | |
ram_enable <= 1; | |
written <= 1; | |
end | |
end | |
else | |
begin | |
if (cmd_ready && fetching) | |
begin | |
// read cycles | |
ram_addr <= ((counter_y << 10) | (fetch_x)); | |
ram_write <= 0; | |
end | |
if (data_out_ready) | |
begin | |
ram_data_buffer[fetch_x] <= ram_data_out; | |
fetch_x <= fetch_x + 1; | |
if (fetch_x > 639) | |
begin | |
fetch_x <= 0; | |
fetching <= 0; | |
end | |
end | |
if (counter_x == 0) begin | |
fetch_x <= 0; | |
fetching <= 1; | |
end | |
end | |
end | |
assign LED1=host_latch; | |
*/ | |
assign hsync = ~vga_HS; | |
assign vsync = ~vga_VS; | |
always @(posedge CLK_IN1) | |
vgaclock <= ~vgaclock; | |
always @(posedge clk) begin | |
if(counter_xmaxed) | |
begin | |
counter_x <= 0; | |
counter_y <= counter_y + 1; | |
end | |
else | |
counter_x <= counter_x + 1; | |
if(counter_y==0 && counter_xmaxed) begin | |
counter_frame <= counter_frame + 1; | |
end | |
vga_HS <= (counter_x[9:4]==0); // active for 16 clocks | |
vga_VS <= (counter_y==0); // active for 768 clocks | |
if (counter_x < 640) begin | |
/* red <= ~vga_HS & ~vga_VS & ram_data_buffer[counter_x][0]; | |
green <= ~vga_HS & ~vga_VS & ram_data_buffer[counter_x][1]; | |
blue <= ~vga_HS & ~vga_VS & ram_data_buffer[counter_x][2];*/ | |
//rgb <= 'hf; | |
//rgb <= 'h0; | |
if ((vga_HS | vga_VS)) | |
rgb <= 0; | |
else begin | |
if (counter_y>400) begin | |
if (counter_x<190) | |
rgb <= 0; | |
else if (counter_x<270) | |
rgb <= (cycle==0)?'b0000011111111111:0; | |
else if (counter_x<350) | |
rgb <= (!bas)?'b0000011111100000:0; | |
else if (counter_x<430) | |
rgb <= e7m?'b0000000000011111:0; | |
else | |
rgb <= 'hffff; | |
end else if (counter_y>200) begin | |
if (counter_x<190) | |
rgb <= 0; | |
else if (counter_x<200) | |
rgb <= z_addr_buffer[23]?'hf00f:'h00; | |
else if (counter_x<210) | |
rgb <= z_addr_buffer[22]?'hff00:'h00; | |
else if (counter_x<220) | |
rgb <= z_addr_buffer[21]?'hf00f:'h00; | |
else if (counter_x<230) | |
rgb <= z_addr_buffer[20]?'hffff:'h00; | |
else if (counter_x<240) | |
rgb <= z_addr_buffer[19]?'hf00f:'h00; | |
else if (counter_x<250) | |
rgb <= z_addr_buffer[18]?'hffff:'h00; | |
else if (counter_x<260) | |
rgb <= z_addr_buffer[17]?'hf00f:'h00; | |
else if (counter_x<270) | |
rgb <= z_addr_buffer[16]?'hffff:'h00; | |
else if (counter_x<280) | |
rgb <= z_addr_buffer[15]?'hff00:'h00; | |
else if (counter_x<290) | |
rgb <= z_addr_buffer[14]?'hffff:'h00; | |
else if (counter_x<300) | |
rgb <= z_addr_buffer[13]?'hf00f:'h00; | |
else if (counter_x<310) | |
rgb <= z_addr_buffer[12]?'hffff:'h00; | |
else if (counter_x<320) | |
rgb <= z_addr_buffer[11]?'hf00f:'h00; | |
else if (counter_x<330) | |
rgb <= z_addr_buffer[10]?'hffff:'h00; | |
else if (counter_x<340) | |
rgb <= z_addr_buffer[9]?'hf00f:'h00; | |
else if (counter_x<350) | |
rgb <= z_addr_buffer[8]?'hffff:'h00; | |
else if (counter_x<360) | |
rgb <= z_addr_buffer[7]?'hff00:'h00; | |
else if (counter_x<370) | |
rgb <= z_addr_buffer[6]?'hffff:'h00; | |
else if (counter_x<380) | |
rgb <= z_addr_buffer[5]?'hf00f:'h00; | |
else if (counter_x<390) | |
rgb <= z_addr_buffer[4]?'hffff:'h00; | |
else if (counter_x<400) | |
rgb <= z_addr_buffer[3]?'hf00f:'h00; | |
else if (counter_x<410) | |
rgb <= z_addr_buffer[2]?'hffff:'h00; | |
else if (counter_x<420) | |
rgb <= z_addr_buffer[1]?'hf00f:'h00; | |
else if (counter_x<430) | |
rgb <= z_addr_buffer[0]?'hffff:'h00; | |
else | |
rgb <= 0; | |
end else if (counter_y>100) begin | |
rgb <= (z_host_write)?'b1111100000011111:0; | |
end else begin | |
/*case (z_state) | |
Z_UNCONFIGURED: rgb<=0; | |
Z_CONF_ROM: rgb <= 'b1111100000000000; | |
Z_CONF_RAM: rgb <= 'b0000011111100000; | |
Z_CONF_DONE: rgb <= 'b0000000000011111; | |
endcase*/ | |
if (counter_x<200) rgb <= (errors[0]==1)?'hffff:0; | |
else if (counter_x<300) rgb <= (errors[1]==1)?'heeee:0; | |
else if (counter_x<400) rgb <= (errors[2]==1)?'hdddd:0; | |
else if (counter_x<500) rgb <= (errors[3]==1)?'hcccc:0; | |
else rgb <= 0; | |
end | |
end | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment