// 水平同期(h_sync)、垂直同期(v_sync)、表示期間(display_on)
`default_nettype none
`timescale 1ns / 1ps
module disp_timing # (
parameter integer RESOLUTION = 1 // SVGA
)
(clk, reset, page_start, display_on, h_addr, v_addr, h_sync, h_sync_pulse, v_sync);
`include "video_timing_param.vh"
`include "convenient_functions.vh"
input clk; // 25MHz
input reset;
output page_start; // 1ページのスタート信号、ページの最初の表示ビットのときにだけ1(同期用信号)
output display_on; // 表示期間を示す(Active High)
output [log2(H_SUM)-1:0] h_addr; // 水平のドットアドレス
output [log2(V_SUM)-1:0] v_addr; // 垂直のドットアドレス
output h_sync; // 水平同期、Active High
output h_sync_pulse; // 水平同期パルス
output v_sync; // 垂直同期、Active High
wire clk;
wire reset;
wire page_start;
wire display_on;
wire [log2(H_SUM)-1:0] h_addr; // 水平のドットアドレス
wire [log2(V_SUM)-1:0] v_addr; // 垂直のドットアドレス
wire h_sync;
wire h_sync_pulse;
wire v_sync;
reg [log2(H_SUM)-1:0] h_point, h_addr_node;
reg [log2(V_SUM)-1:0] v_point, v_addr_node;
reg page_start_node;
reg display_on_node;
reg h_sync_node;
reg v_sync_node;
reg h_sync_pulse_node;
always @(posedge reset, posedge clk) begin // 水平信号
if (reset) begin
h_point <= 0;
h_addr_node <= 0;
end else begin
h_addr_node <= h_point;
if (h_point == H_SUM-1) // H_SUM-1だったらクリア
h_point <= 0;
else // H_SUM-1になるまでインクリメント
h_point <= h_point + 1;
end
end
assign h_addr = h_addr_node[9:0];
always @(posedge reset, posedge clk) begin // 垂直信号
if (reset) begin
v_point <= 0;
v_addr_node <= 0;
end else begin
v_addr_node <= v_point;
if (v_point == V_SUM-1) // H_SUM-1だったらクリア
v_point <= 0;
else if (h_point == H_SUM-1) // 水平信号のエンドでインクリメント
v_point <= v_point + 1;
end
end
assign v_addr = v_addr_node[9:0];
always @(posedge reset, posedge clk) begin // 表示期間
if (reset)
display_on_node <= 0;
else begin
if (h_point<H_ACTIVE_VIDEO && v_point<V_ACTIVE_VIDEO) // 表示期間
display_on_node <= 1'b1;
else
display_on_node <= 1'b0; // 非表示期間
end
end
assign display_on = display_on_node;
always @(posedge reset, posedge clk) begin // 表示スタート
if (reset)
page_start_node <= 1'b0;
else begin
if (h_point==0) // 表示スタート
page_start_node <= 1'b1;
else
page_start_node <= 1'b0;
end
end
assign page_start = page_start_node;
always @(posedge reset, posedge clk) begin // 水平同期
if (reset)
h_sync_node <= 1'b0;
else begin
if ((h_point>=(H_ACTIVE_VIDEO + H_FRONT_PORCH)) && (h_point < (H_SUM-H_BACK_PORCH))) // 水平同期期間
h_sync_node <= 1'b1;
else
h_sync_node <= 1'b0;
end
end
assign h_sync = h_sync_node;
always @(posedge reset, posedge clk) begin // 水平同期位置のパルス
if (reset)
h_sync_pulse_node <= 1'b0;
else begin
if (h_point==(H_ACTIVE_VIDEO+H_FRONT_PORCH))
h_sync_pulse_node <= 1'b1;
else
h_sync_pulse_node <= 1'b0;
end
end
assign h_sync_pulse = h_sync_pulse_node;
always @(posedge reset, posedge clk) begin // 垂直同期
if (reset)
v_sync_node <= 1'b0;
else begin
if ((v_point>=(V_ACTIVE_VIDEO + V_FRONT_PORCH)) && (v_point<(V_SUM-V_BACK_PORCH))) // 垂直同期期間
v_sync_node <= 1'b1;
else
v_sync_node <= 1'b0;
end
end
assign v_sync = v_sync_node;
endmodule
// フレームバッファ用メモリ
// AポートはプロセッサからのRead/Write用ポート、BポートはVGA用データ出力ポート
// display_on信号を受け取って、フレームバッファ用のアドレスを生成。このアドレスは8クロックごとにカウントアップ。
// データはキャラクタコード7ビットにR,G,Bの3ビットを追加
//
// 2012/02/24 : R 3bit, G 3bit, B 3bit, キャラクタ 7bitの16ビットに変更した。
// 2012/02/25 : Write側とRead側のクロックを分離して、非同期RAMに変更した。
// 2013/03/05 : reset を reset_a, reset_b に変更
// 2014/03/16 : 全面変更
`default_nettype none
module frame_buffer # (
parameter integer RESOLUTION = 1 // SVGA
)
(clka, clkb, reset_a, reset_b, processor_addr, processor_din, processor_dout, processor_we, display_addr, display_dout);
`include "video_timing_param.vh"
`include "convenient_functions.vh"
input clka;
input clkb;
input reset_a;
input reset_b;
input [log2(ALL_CHAR_SIZE)-1:0] processor_addr;
input [15:0] processor_din;
output [15:0] processor_dout;
input processor_we;
input [log2(ALL_CHAR_SIZE)-1:0] display_addr;
output [15:0] display_dout;
parameter integer FB_MEM_SIZE = near_power2(ALL_CHAR_SIZE);
reg [15:0] mem [0:near_power2(ALL_CHAR_SIZE)-1];
wire clka;
wire clkb;
wire reset_a;
wire reset_b;
wire [log2(ALL_CHAR_SIZE)-1:0] processor_addr;
wire [15:0] processor_din;
reg [15:0] processor_dout;
wire processor_we;
wire [log2(ALL_CHAR_SIZE)-1:0] display_addr;
reg [15:0] display_dout;
integer i;
// initialization
// Simulation では通るが、Synthesize だと、どうしてもエラーになるので Simulation のみとした
// pragma translate off
initial begin
for (i=0; i<FB_MEM_SIZE; i=i+1) begin
mem[i] = 16'd0;
end
end
// pragma translate on
// Write
always @(posedge clka) begin
if (processor_we)
mem[processor_addr] <= processor_din;
processor_dout <= mem[processor_addr];
end
// Read
always @(posedge clkb) begin
display_dout <= mem[display_addr];
end
endmodule
`default_nettype none
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | - | 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 |