Код:
module LA(
input wire CLK14,
// Video in
input wire IR,
input wire IG,
input wire IB,
input wire II,
input wire ISSI,
input wire IKSI,
input wire[3:0] SW,
//Video out
output reg QR,
output reg QB,
output reg QG,
output reg QI,
output reg KSI,
output reg SSI,
// RAM
output reg [17:0] RAM_AQ,
inout wire[15:0] RAM_DB,
output wire RAM_WE,
output reg RAM_OE,
output wire RAM_UE,
output wire RAM_LE
);
parameter H_SYNC_CYC = 40;
parameter H_SYNC_BACK = 20;
parameter H_SYNC_ACT = 384;
parameter H_SYNC_FRONT= 4;
parameter H_SYNC_TOTAL= 447;
parameter V_SYNC_CYC = 2;
parameter V_SYNC_BACK = 46;
parameter V_SYNC_ACT = 576;
parameter V_SYNC_FRONT= 15;
parameter V_SYNC_TOTAL= 640;
reg HBLANK, VBLANK;
reg [9:0] VCNT, HCNT;
reg [17:0] RAMCNT;
reg [7:0] RAM_DQ;
reg [7:0] SHIFT;
reg WR;
assign RAM_WE = WR | CLK14;
assign RAM_UE = 1'b0;
assign RAM_LE = 1'b0;
assign RAM_DB[7:0] = (!RAM_WE) ? RAM_DQ : 8'hZZ;
reg [3:0] RDMUX;
reg [1:0] KEY, VAL_R, VAL_G, VAL_B, VAL_I, SHIFT_L, SHIFT_R;
always@(posedge CLK14)
begin
RDMUX = (HCNT[0]) ? RAM_DB[7:4] : RAM_DB[3:0];
KEY = {SW[0], KEY[1]};
VAL_R = { RDMUX[3], VAL_R[1] };
VAL_G = { RDMUX[2], VAL_G[1] };
VAL_B = { RDMUX[1], VAL_B[1] };
VAL_I = { RDMUX[0], VAL_I[1] };
SHIFT = {SHIFT[3:0], IR,IG,IB,II};
if (KEY[0] != KEY[1])
begin
RAMCNT = 0;
WR = 1'b1;
if (!KEY[1])
RAM_OE = 1'b1; // write
else
RAM_OE = 1'b0; // read
end
// mem unit
if (RAM_OE)
begin
if (!HCNT[0])
begin
RAM_AQ = RAMCNT;
RAM_DQ = SHIFT;
end
else
RAMCNT = !RAMCNT[17] ? RAMCNT + 1 : RAMCNT;
WR = HCNT[0];
end
else
begin
end
HBLANK <= (HCNT <= H_SYNC_CYC+ H_SYNC_BACK || HCNT >= H_SYNC_TOTAL - H_SYNC_FRONT);
// H_Sync Counter
if( HCNT < H_SYNC_TOTAL )
HCNT <= HCNT+1;
else
HCNT <= 0;
// H_Sync Generator
if( HCNT < H_SYNC_CYC )
SSI <= 0;
else
begin
SSI <= 1;
if (!RAM_OE)
RAM_AQ[17:0] = {RAMCNT[10:0], HCNT[8:1]};
end
if (BLANK)
{QR, QG, QB, QI} = 4'h0;
else
begin
QR = PEN_R | PEN_I;
QG = PEN_G | PEN_I;
QB = PEN_B | PEN_I;
QI = (RAY_R | RAY_G | RAY_B | RAY_I) & HCNT[2:0] == 0 & VCNT[3:0] == 0;
end
end
wire LH = VCNT[5:2] == 4'h0;
wire LL = VCNT[5:2] == 4'hF;
wire RAY_R = VCNT[9:6] == 4'h1;
wire RAY_G = VCNT[9:6] == 4'h3;
wire RAY_B = VCNT[9:6] == 4'h5;
wire RAY_I = VCNT[9:6] == 4'h7;
wire PEN_R = RAY_R & (VAL_R[0]==VAL_R[1] ? (VAL_R[1] ? LH : LL) : 1'b1);
wire PEN_G = RAY_G & (VAL_G[0]==VAL_G[1] ? (VAL_G[1] ? LH : LL) : 1'b1);
wire PEN_B = RAY_B & (VAL_B[0]==VAL_B[1] ? (VAL_B[1] ? LH : LL) : 1'b1);
wire PEN_I = RAY_I & (VAL_I[0]==VAL_I[1] ? (VAL_I[1] ? LH : LL) : 1'b1);
always@(posedge CLK14)
begin
if(HCNT==0)
begin
// V_Sync Counter
if( VCNT < V_SYNC_TOTAL )
VCNT <= VCNT+1;
else
VCNT <= 0;
// V_Sync Generator
if( VCNT < V_SYNC_CYC )
begin
KSI <= 0;
SHIFT_L = {SW[3], SHIFT_L[1]};
SHIFT_R = {SW[2], SHIFT_R[1]};
end
else
KSI <= 1;
end
VBLANK <= (VCNT < V_SYNC_BACK || VCNT >= V_SYNC_BACK + V_SYNC_ACT);
end
assign BLANK = VBLANK | HBLANK;
endmodule