143 lines
3.0 KiB
Verilog
143 lines
3.0 KiB
Verilog
module main(
|
|
// 50MHz clock input
|
|
input clk,
|
|
// Input from reset button (active low)
|
|
input rst_n,
|
|
// Outputs to the 8 onboard LEDs
|
|
output[7:0]led,
|
|
output[3:0] hdmi1_tmds,
|
|
output[3:0] hdmi1_tmdsb,
|
|
input zclk,
|
|
input zioreq,
|
|
input zwr,
|
|
input zm1,
|
|
input zrd,
|
|
input[7:0] zdata,
|
|
input[3:0] zaddr
|
|
);
|
|
|
|
wire rst = ~rst_n; // make reset active high
|
|
reg [7:0] red, green, blue;
|
|
wire [11:0] x;
|
|
wire [10:0] y;
|
|
wire [5:0] scroll;
|
|
reg[3:0] charx;
|
|
reg[3:0] chary;
|
|
wire hclk;
|
|
wire mclk;
|
|
wire [15:0] xy;
|
|
wire [7:0] screen_x;
|
|
wire [7:0] screen_y;
|
|
reg [12:0] waddr;
|
|
wire [15:0] write_data;
|
|
wire write_enable;
|
|
|
|
reg [12:0] raddr;
|
|
wire [15:0] read_data;
|
|
wire [255:0] char;
|
|
|
|
reg [1:0] control_in;
|
|
// 0 Correct address
|
|
// 1 Write
|
|
|
|
wire[23:0] foreground;
|
|
wire[23:0] background;
|
|
|
|
assign led[5:0] = scroll[5:0];
|
|
assign led[7:6] = 0;
|
|
|
|
assign screen_x[7:0] = xy[7:0];
|
|
assign screen_y[7:0] = xy[15:8];
|
|
|
|
hdmi_clk hdmi_clk(.CLK_IN1(clk), .CLK_OUT1(hclk), .CLK_OUT2(mclk));
|
|
|
|
localparam HEIGHT = 720;
|
|
localparam WIDTH = 1280;
|
|
hdmi_encoder #(.Y_RES(HEIGHT), .X_RES(WIDTH), .Y_FRAME(HEIGHT+2*16), .X_FRAME(WIDTH+24*16)) hdmi(
|
|
.clk(hclk),
|
|
.rst(rst),
|
|
.tmds(hdmi1_tmds),
|
|
.tmdsb(hdmi1_tmdsb),
|
|
.x(x),
|
|
.y(y),
|
|
.red(red),
|
|
.green(green),
|
|
.blue(blue)
|
|
);
|
|
|
|
microblaze_mcs mcs_0 (
|
|
.Clk(mclk), // input Clk
|
|
.Reset(rst), // input Reset
|
|
.GPO1(write_data), // output [15 : 0] GPO1
|
|
.GPO2(xy), // output [15 : 0] GPO2
|
|
.GPO3(write_enable), // output [0 : 0] GPO3
|
|
.GPO4(scroll), // output [5 : 0] GPO4
|
|
.GPI1(zdata), // input [7 : 0] GPI1
|
|
.GPI1_Interrupt(), // output GPI1_Interrupt
|
|
.GPI2(zclk), // input [0 : 0] GPI2
|
|
.GPI2_Interrupt(), // output GPI2_Interrupt
|
|
.GPI3(control_in), // input [1 : 0] GPI3
|
|
.GPI3_Interrupt(), // output GPI3_Interrupt
|
|
.INTC_IRQ() // output INTC_IRQ
|
|
);
|
|
|
|
simple_dual_ram #(.SIZE(16), .DEPTH((80+24)*(45+2))) sram (
|
|
.wclk(mclk),
|
|
.waddr(waddr),
|
|
.write_data(write_data),
|
|
.write_en(write_enable),
|
|
.rclk(hclk),
|
|
.raddr(raddr),
|
|
.read_data(read_data)
|
|
);
|
|
|
|
char_map char_map (
|
|
.clk(hclk),
|
|
.index(read_data[7:0]),
|
|
.char(char)
|
|
);
|
|
|
|
color_map foreground_map (
|
|
.clk(hclk),
|
|
.colorcode(read_data[11:8]),
|
|
.color(foreground)
|
|
);
|
|
|
|
color_map backgroundground_map (
|
|
.clk(hclk),
|
|
.colorcode(read_data[15:12]),
|
|
.color(background)
|
|
);
|
|
|
|
always @(*) begin
|
|
charx = (x >> 0) % 16;
|
|
chary = (y >> 0) % 16;
|
|
|
|
waddr = (screen_x % (80+24)) + (80+24)*((screen_y + scroll) % (45+2));
|
|
raddr = (((x+2) >> 4) % (80+24)) + (80+24)*((( (x > WIDTH) ? ((y+1) >> 4) : (y >> 4) ) + scroll) % (45+2));
|
|
|
|
if (zaddr == 4'h02) begin
|
|
control_in[0] = 1;
|
|
end else begin
|
|
control_in[0] = 0;
|
|
end
|
|
|
|
if (zioreq == 0 && zm1 == 1 && zwr == 0) begin
|
|
control_in[1] = 1;
|
|
end else begin
|
|
control_in[1] = 0;
|
|
end
|
|
|
|
// @todo Instead of doing + 17 we safe space in the char rom
|
|
if (char[255 - charx - 16*chary] == 1) begin
|
|
red = foreground[23:16];
|
|
green = foreground[15:8];
|
|
blue = foreground[7:0];
|
|
end else begin
|
|
red = background[23:16];
|
|
green = background[15:8];
|
|
blue = background[7:0];
|
|
end
|
|
end
|
|
|
|
endmodule |