x + 640 x 480 x y = 68sec ----- (1)
x + 80 x 60 x y = 2 ----- (2)
(640 x 480 - 80 x 60) x y = 68 - 2
y = 21 x 10の-6乗 = 21 usec
-63x = -60
x = 60/63 = 0.95 sec
/*
* drawn_disp.c
*
* Created on: 2012/09/25
* Author: Masaaki
*/
#include "xparameters.h"
#include "xgpio.h"
#define VIDEO_BUFFER_START_ADDRESS 0x10000000
void Xil_DCacheFlush(void);
// char_draw: アドレスとキャラクタコードを受け取ってそのキャラクタを描画する
// addr : 描画するキャラクタのスタートアドレス
// char_code : 描画するキャラクタのコード
// char_color : 描画するキャラクタのカラー、32ビットで表される、0RGBと8ビットずつで表す
// 戻り値:次のキャラクタの描画先頭アドレスを示す。
unsigned int *char_draw(unsigned int *addr, unsigned char char_code, unsigned int char_color){
int i,j;
unsigned int char_pattern;
unsigned int char_code_int;
unsigned int *cal_char_addr;
unsigned int *return_addr;
char_code_int = (unsigned int)(char_code);
return_addr = addr + 8;
cal_char_addr = (unsigned int *)(XPAR_CHAR_ROM_AXI_LITE_0_S_AXI_RNG00_BASEADDR+((char_code_int<<3)<<2)); // キャラジェネROMのデータは32ビット幅で下の8ビットだけ有効
for(i=0; i<8; i++){
char_pattern = *(volatile unsigned int *)(cal_char_addr); // キャラクタのパターンを読み出し
for(j=0; j<8; j++){
if(char_pattern & 0x1) // 7ビット目が1の時はドットを描画
*(volatile unsigned int *)((unsigned int)addr ^ 4) = char_color;
else
*(volatile unsigned int *)((unsigned int)addr ^ 4) = 0; // 黒を描画
// Xil_DCacheFlush(); // 1番目の時間計測
addr++;
char_pattern >>= 1; // キャラクタのパターンを1ビット右シフト
}
addr -= 8; // 行の最初のアドレスに戻す
addr += 640; // アドレスを1行下にする
cal_char_addr++;
}
// Xil_DCacheFlush(); // 2番目の時間計測
return return_addr;
}
int main()
{
static XGpio GPIOInstance_Ptr;
int xStatus;
unsigned char char_code;
unsigned int * ddr2_addr;
unsigned int coler_code;
unsigned int char_cnt;
int i, j;
// AXI GPIO Initialization
xStatus = XGpio_Initialize(&GPIOInstance_Ptr,XPAR_AXI_GPIO_0_DEVICE_ID);
if(XST_SUCCESS != xStatus)
print("GPIO INIT FAILED\n\r");
// AXI GPIO Set the Direction(Output setting)
XGpio_SetDataDirection(&GPIOInstance_Ptr, 1, 0);
// init_doneに1を出力
XGpio_DiscreteWrite(&GPIOInstance_Ptr, 1, 1);
for (ddr2_addr=(unsigned int *)VIDEO_BUFFER_START_ADDRESS; ddr2_addr<(unsigned int *)((unsigned int)VIDEO_BUFFER_START_ADDRESS + (unsigned int)0x12C000); ddr2_addr++){
*(volatile unsigned int *)((unsigned int)ddr2_addr ^ 4) = 0;
}
Xil_DCacheFlush();
ddr2_addr = (unsigned int *)VIDEO_BUFFER_START_ADDRESS;
char_cnt = 0;
for(j=0; j<8; j++){
for(i=1; i<8; i++){
switch(i){
case 1 :
coler_code = 0xff;
break;
case 2 :
coler_code = 0xff00;
break;
case 3 :
coler_code = 0xffff;
break;
case 4 :
coler_code = 0xff0000;
break;
case 5 :
coler_code = 0xff00ff;
break;
case 6 :
coler_code = 0xffff00;
break;
case 7 :
coler_code = 0xffffff;
}
for(char_code=0x21; char_code<0x80; char_code++){
if(char_code >= 0x80) // キャラクタコードが上限に達したら、一番下に戻す
char_code = 0x21;
if (char_cnt!=0 && char_cnt%80==0)
ddr2_addr = (unsigned int *)((unsigned int)ddr2_addr + 640*4*7); // 1行書き終わったので、下の行に、アドレスは640ドットx1ピクセル4バイトx7行
ddr2_addr = char_draw(ddr2_addr, char_code, coler_code); // キャラクタを描画
char_cnt++;
}
}
}
Xil_DCacheFlush(); // 3番めの時間計測
return 0;
}
fpga -debugdevice devicenr 2 -f cf_adv7511_zed.bit
connect arm hw
source ps7_init.tcl
ps7_init
dow cf_adv7511_zed.elf
run
disconnect 64
exit
// OVL_Checker.v
// 2012/10/25:書き込みトランザクションの時に、MasterがAWREADYを待って、WVALIDをアサートしていけないというルールがあったので、修正した。
//
`default_nettype none
`timescale 100ps / 1ps
`include "std_ovl_defines.h"
module OVL_Checker (
input wire ACLK,
input wire ARESETN,
input wire [0:0] S_AXI_AWID,
input wire [31:0] S_AXI_AWADDR,
input wire [7:0] S_AXI_AWLEN,
input wire [2:0] S_AXI_AWSIZE,
input wire [1:0] S_AXI_AWBURST,
input wire [1:0] S_AXI_AWLOCK,
input wire [3:0] S_AXI_AWCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_AWPROT,
input wire [3:0] S_AXI_AWREGION,
input wire [3:0] S_AXI_AWQOS,
input wire [0:0] S_AXI_AWUSER,
input wire S_AXI_AWVALID,
input wire [0:0] S_AXI_WID,
input wire [31:0] S_AXI_WDATA,
input wire [3:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire [0:0] S_AXI_WUSER,
input wire S_AXI_WVALID,
input wire S_AXI_BREADY,
input wire [0:0] S_AXI_ARID,
input wire [31:0] S_AXI_ARADDR,
input wire [7:0] S_AXI_ARLEN,
input wire [2:0] S_AXI_ARSIZE,
input wire [1:0] S_AXI_ARBURST,
input wire [1:0] S_AXI_ARLOCK,
input wire [3:0] S_AXI_ARCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_ARPROT,
input wire [3:0] S_AXI_ARREGION,
input wire [3:0] S_AXI_ARQOS,
input wire [0:0] S_AXI_ARUSER,
input wire S_AXI_ARVALID,
input wire S_AXI_RREADY,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
wire [`OVL_FIRE_WIDTH-1:0] fire_wr_data, fire_rd_data;
wire [`OVL_FIRE_WIDTH-1:0] fire_aw_hcheck, fire_ar_hcheck;
wire [`OVL_FIRE_WIDTH-1:0] fire_awvalid_cont, fire_wd_sig_assert;
wire [`OVL_FIRE_WIDTH-1:0] fire_ar_never;
reg [7:0] countw, countr;
parameter idle_wts = 3'b001,
wr_data_tran = 3'b010,
wr_resp_tran = 3'b100;
reg [2:0] wr_tran_cs;
parameter idle_rts = 1'b0,
rd_data_tran = 1'b1;
reg rd_trans_cs;
// Wirte Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Write data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) wr_data_check (
ACLK, // clock
~ARESETN | (S_AXI_AWVALID & S_AXI_AWREADY), // reset, Write のアドレス転送でリセット
S_AXI_WVALID & S_AXI_WREADY, // enable
S_AXI_WDATA, // test_expr
fire_wr_data // fire parameter
);
// Read Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Read data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) rd_data_check (
ACLK, // clock
~ARESETN | (S_AXI_ARVALID & S_AXI_ARREADY), // reset, Read のアドレス転送でリセット
S_AXI_RVALID & S_AXI_RREADY, // enable
S_AXI_RDATA, // test_expr
fire_rd_data // fire parameter
);
// S_AXI_AWVALID とS_AXI_AWREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_AWREADY and S_AXI_AWVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) aw_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // req
S_AXI_AWREADY, // ack
fire_aw_hcheck // fire parameter
);
// S_AXI_ARVALID とS_AXI_ARREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_ARREADY and S_AXI_ARVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_ARVALID, // req
S_AXI_ARREADY, // ack
fire_ar_hcheck // fire parameter
);
// Write, S_AXI_AWREADY がアサートされるとき、次のクロックでS_AXI_AWVALIDがディアサートされる
ovl_transition #(
`OVL_ERROR, // severity_level
1, // width
`OVL_ASSERT, // property_type
"Error : Assert of S_AXI_AWVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) awvalid_cont_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // test_expr
S_AXI_AWREADY & S_AXI_AWVALID, // start_state
~S_AXI_AWVALID, // next_state
fire_awvalid_cont
);
// Write, S_AXI_WVALID, S_AXI_WLAST, S_AXI_WREADYがアサートされるとき、次のクロックで、それらの信号がディアサートされる
ovl_transition #(
`OVL_ERROR, // severity_level
1, // width
`OVL_ASSERT, // property_type
"Error : Assert of S_AXI_WVALID or S_AXI_WLAST or S_AXI_WREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) wd_sig_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // test_expr
S_AXI_WVALID & S_AXI_WLAST & S_AXI_WREADY, // start_state
~(S_AXI_WVALID | S_AXI_WLAST | S_AXI_WREADY), // next_state
fire_wd_sig_assert
);
// Read, S_AXI_RREADY がアサートされるときは、 S_AXI_RVALID, S_AXI_RREADY, S_AXI_RLAST はアサートされない
ovl_never #(
`OVL_ERROR, // severity_level
`OVL_ASSERT, // property_type
"Read, Assert Error of S_AXI_RREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_never_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST),
fire_ar_never
);
// Write の転送数をカウントして、 S_AXI_WLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countw <= 0;
else begin
if (S_AXI_AWVALID & S_AXI_AWREADY) begin // countw へロード
countw <= S_AXI_AWLEN;
end else if (S_AXI_WVALID & S_AXI_WREADY) begin // データ転送
if (countw==0) begin // データ転送終了
if (~S_AXI_WLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countw==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Read の転送数をカウントして、 S_AXI_RLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countr <= 0;
else begin
if (S_AXI_ARVALID & S_AXI_ARREADY) begin // countw へロード
countr <= S_AXI_ARLEN;
end else if (S_AXI_RVALID & S_AXI_RREADY) begin // データ転送
if (countr==0) begin // データ転送終了
if (~S_AXI_RLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countr==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Write 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
wr_tran_cs <= idle_wts;
else begin
case (wr_tran_cs)
idle_wts :
if (S_AXI_AWREADY & (S_AXI_BREADY)) // エラー
$display("%m: at time %t S_AXI_AWREADY がアサートされた時に、BREADY信号がアサートされた",$time);
else if (S_AXI_AWVALID & S_AXI_AWREADY) // アドレス転送終了
wr_tran_cs <= wr_data_tran;
wr_data_tran :
if (S_AXI_BREADY) // エラー
$display("%m: at time %t Write データ転送中に、S_AXI_BREADY がアサートされた",$time);
else if (S_AXI_WVALID & S_AXI_WREADY & S_AXI_WLAST) // データ転送終了
wr_tran_cs <= wr_resp_tran;
wr_resp_tran :
if (S_AXI_AWREADY | S_AXI_WVALID | S_AXI_WREADY | S_AXI_WLAST) // エラー
$display("%m: at time %t Write Response Channel 転送時に関連しない信号がアサートされた",$time);
else if (S_AXI_BVALID & S_AXI_BREADY) // Write Response Channel 転送終了
wr_tran_cs <= idle_wts;
endcase
end
end
// Read 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
rd_trans_cs <= idle_rts;
else begin
case (rd_trans_cs)
idle_rts :
if (S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST)) // エラー
$display("%m: at time %t S_AXI_ARREADY がアサートされた時に、その他のVALID, READY信号がアサートされた",$time);
else if (S_AXI_ARVALID & S_AXI_ARREADY) // アドレス転送終了
rd_trans_cs <= rd_data_tran;
rd_data_tran :
if (S_AXI_ARREADY) // エラー
$display("%m: at time %t Read データ転送中に、S_AXI_ARREADY がアサートされた",$time);
else if (S_AXI_RVALID & S_AXI_RREADY & S_AXI_RLAST) // データ転送終了
rd_trans_cs <= idle_rts;
endcase
end
end
endmodule
`default_nettype wire
Command Line: fuse -intstyle ise -incremental -i K:/HDL/OVL/std_ovl_v2p6 -d OVL_VERILOG -d OVL_ASSERT_ON -d OVL_FINISH_OFF -lib unisims_ver -lib unimacro_ver -lib xilinxcorelib_ver -lib secureip -o H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_isim_beh.exe -prj H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_beh.prj work.CDC_axi_slave_tb work.glbl {-L accellera_ovl_vlog=K:\HDL\Xilinx\13.4\ISE_DS\ISE\verilog\hdp\nt\accellera_ovl_vlog}
Running: K:\HDL\Xilinx\14.1\ISE_DS\ISE\bin\nt\unwrapped\fuse.exe -intstyle ise -incremental -i K:/HDL/OVL/std_ovl_v2p6 -d OVL_VERILOG -d OVL_ASSERT_ON -d OVL_FINISH_OFF -lib unisims_ver -lib unimacro_ver -lib xilinxcorelib_ver -lib secureip -o H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_isim_beh.exe -prj H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_beh.prj work.CDC_axi_slave_tb work.glbl -L accellera_ovl_vlog=K:\HDL\Xilinx\13.4\ISE_DS\ISE\verilog\hdp\nt\accellera_ovl_vlog
// AXI4 bus Master Bus Fucntion Mode
// 2012/10/24 : 修正、S_AXI_AWREADYが1になるのを確認してからS_AXI_WVALIDを1にしていたのでは、AXIバスの非標準となる。
// よって、AXI_MASTER_WAC とAXI_MASTER_WDC をfork ~ join で並列に実行する
// 2013/12/14 : input に DELAYを入れるように変更
//
`default_nettype none
`timescale 100ps / 1ps
module AXI4_Master_BFM #(
parameter DELAY = 10 )
(
input wire ACLK,
output reg [0:0] S_AXI_AWID = 0,
output reg [31:0] S_AXI_AWADDR = 0,
output reg [7:0] S_AXI_AWLEN = 0,
output reg [2:0] S_AXI_AWSIZE = 0,
output reg [1:0] S_AXI_AWBURST = 0,
output reg [1:0] S_AXI_AWLOCK = 0,
output reg [3:0] S_AXI_AWCACHE = 3, // Normal Non-cacheable bufferable
output reg [2:0] S_AXI_AWPROT = 0,
output reg [3:0] S_AXI_AWREGION = 0,
output reg [3:0] S_AXI_AWQOS = 0,
output reg [0:0] S_AXI_AWUSER = 0,
output reg S_AXI_AWVALID = 0,
output reg [0:0] S_AXI_WID = 0,
output reg [31:0] S_AXI_WDATA = 0,
output reg [3:0] S_AXI_WSTRB = 0,
output reg S_AXI_WLAST = 0,
output reg [0:0] S_AXI_WUSER = 0,
output reg S_AXI_WVALID = 0,
output reg S_AXI_BREADY = 0,
output reg [0:0] S_AXI_ARID = 0,
output reg [31:0] S_AXI_ARADDR = 0,
output reg [7:0] S_AXI_ARLEN = 0,
output reg [2:0] S_AXI_ARSIZE = 0,
output reg [1:0] S_AXI_ARBURST = 0,
output reg [1:0] S_AXI_ARLOCK = 0,
output reg [3:0] S_AXI_ARCACHE = 2, // Normal Non-cacheable bufferable
output reg [2:0] S_AXI_ARPROT = 0,
output reg [3:0] S_AXI_ARREGION = 0,
output reg [3:0] S_AXI_ARQOS = 0,
output reg [0:0] S_AXI_ARUSER = 0,
output reg S_AXI_ARVALID = 0,
output reg S_AXI_RREADY = 0,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
reg [7:0] awlen_hold = 0;
reg [0:0] wid_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
reg S_AXI_AWREADY_d;
reg S_AXI_WREADY_d;
reg [0:0] S_AXI_BID_d;
reg [1:0] S_AXI_BRESP_d;
reg [0:0] S_AXI_BUSER_d;
reg S_AXI_BVALID_d;
reg S_AXI_ARREADY_d;
reg [0:0] S_AXI_RID_d;
reg [31:0] S_AXI_RDATA_d;
reg [1:0] S_AXI_RRESP_d;
reg S_AXI_RLAST_d;
reg [0:0] S_AXI_RUSER_d;
reg S_AXI_RVALID_d;
always @* S_AXI_AWREADY_d <= #DELAY S_AXI_AWREADY;
always @* S_AXI_WREADY_d <= #DELAY S_AXI_WREADY;
always @* S_AXI_BID_d <= #DELAY S_AXI_BID;
always @* S_AXI_BRESP_d <= #DELAY S_AXI_BRESP;
always @* S_AXI_BUSER_d <= #DELAY S_AXI_BUSER;
always @* S_AXI_BVALID_d <= #DELAY S_AXI_BVALID;
always @* S_AXI_ARREADY_d <= #DELAY S_AXI_ARREADY;
always @* S_AXI_RID_d <= #DELAY S_AXI_RID;
always @* S_AXI_RDATA_d <= #DELAY S_AXI_RDATA;
always @* S_AXI_RRESP_d <= #DELAY S_AXI_RRESP;
always @* S_AXI_RLAST_d <= #DELAY S_AXI_RLAST;
always @* S_AXI_RUSER_d <= #DELAY S_AXI_RUSER;
always @* S_AXI_RVALID_d <= #DELAY S_AXI_RVALID;
// Write Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_Master_1Seq_Write; // Write Address; Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
input [31:0] wdata;
input [7:0] wait_clk_bready;
input [7:0] wmax_wait;
begin
fork
AXI_MASTER_WAC(awid, awaddr, awlen, awsize, awburst);
AXI_MASTER_WDC(wdata, wmax_wait);
join
AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Write Address Channel
task AXI_MASTER_WAC;
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
begin
S_AXI_AWID = awid;
S_AXI_AWADDR = awaddr;
S_AXI_AWLEN = awlen;
S_AXI_AWSIZE = awsize;
S_AXI_AWBURST = awburst;
S_AXI_AWVALID = 1'b1;
if (axi_w_transaction_active == 1'b0) begin // AXI Write トランザクションが開始されている場合は戻る
axi_w_transaction_active = 1'b1; // AXIトランザクション開始
awlen_hold = awlen; // Write Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_AWREADY_d) begin // S_AXI_AWREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
endtask
// Write Data Channel
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_MASTER_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
input [7:0] wmax_wait; // Write時の最大wait数
integer i, j, val;
begin
i = 0; j = 0;
S_AXI_WSTRB = 4'b1111;
while (~S_AXI_AWVALID) begin // S_AXI_AWVALID が1になるまで待つ
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
while (i<=awlen_hold) begin
if (wmax_wait == 0) // wmax_wait が0の時は$random を実行しない
val = 0;
else
val = $unsigned($random) % (wmax_wait+1);
if (val == 0) begin // waitなし
S_AXI_WVALID = 1'b1;
end else begin // waitあり
S_AXI_WVALID = 1'b0;
for (j=0; j<val; j=j+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_WVALID = 1'b1; // wait終了
end
if (i == awlen_hold)
S_AXI_WLAST = 1'b1;
else
S_AXI_WLAST = 1'b0;
S_AXI_WDATA = wdata;
wdata = wdata + 1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_WREADY_d) begin // S_AXI_WREADY が0の時は1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
i = i + 1;
end
S_AXI_WVALID = 1'b0;
S_AXI_WLAST = 1'b0;
S_AXI_WSTRB = 4'b0000;
end
endtask
// Write Response Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
task AXI_MASTER_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
integer i;
begin
for (i=0; i<wait_clk_bready; i=i+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_BREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_BVALID_d) begin // S_AXI_BVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_BREADY = 1'b0;
axi_w_transaction_active = 1'b0; // AXIトランザクション終了
@(posedge ACLK);
#DELAY;
end
endtask
// Read Channel
task AXI_Master_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
input [7:0] rmax_wait; // Read時の最大wait数
begin
AXI_MASTER_RAC(arid, araddr, arlen, arsize, arburst);
AXI_MASTER_RDC(rmax_wait);
end
endtask
// Read Address Channel
task AXI_MASTER_RAC;
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
S_AXI_ARID = arid;
S_AXI_ARADDR = araddr;
S_AXI_ARLEN = arlen;
S_AXI_ARSIZE = arsize;
S_AXI_ARBURST = arburst;
S_AXI_ARVALID = 1'b1;
if (axi_r_transaction_active == 1'b0) begin // AXI Read トランザクションが開始されている場合は戻る
arlen_hold =arlen; // Read Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY_d) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_r_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Read Data Channel
task AXI_MASTER_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
input [7:0] rmax_wait; // Read時の最大wait数
integer i, val;
begin
while (~(S_AXI_RLAST_d & S_AXI_RVALID_d & S_AXI_RREADY)) begin // S_AXI_RLAST & S_AXI_RVALID & S_AXI_RREADY で終了
if (rmax_wait == 0) begin // rmax_wait が0の時は$random を実行しない
val = 0;
S_AXI_RREADY = 1'b1;
end else begin
val = $unsigned($random) % (rmax_wait+1);
if (val == 0)
S_AXI_RREADY = 1'b1;
else
S_AXI_RREADY = 1'b0;
end
#DELAY;
for (i=0; i<val; i=i+1) begin // ランダム値でWait、val=0の時はスキップ
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_RVALID_d) begin // S_AXI_RVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
end
#DELAY;
S_AXI_RREADY = 1'b0;
axi_r_transaction_active = 1'b0; // AXIトランザクション終了
@(posedge ACLK);
#DELAY;
end
endtask
endmodule
`default_nettype wire
// CDC_axi_slave_tb.v
`default_nettype none
`timescale 100ps / 1ps
module CDC_axi_slave_tb;
parameter DELAY = 10;
parameter NUMBER_OF_TEST = 100; // テストする数
parameter ASIZE_BT_4 = 3'd2; // 32 bit width
parameter ASIZE_BT_2 = 3'd1; // 16 bit width
parameter ASIZE_BT_1 = 3'd0; // 8 bit width
parameter ABURST_FIXED = 2'd0;
parameter ABURST_INCR = 2'd1;
parameter ABURST_WRAP = 2'd2;
parameter BRESP_OKAY = 2'b00;
parameter BRESP_EXOKAY = 2'b01;
parameter BRESP_SLVERR = 2'b10;
parameter BRESP_DECERR = 2'b11;
// Inputs
wire ACLK;
wire ARESETN;
wire [0:0] S_AXI_AWID;
wire [31:0] S_AXI_AWADDR;
wire [7:0] S_AXI_AWLEN;
wire [2:0] S_AXI_AWSIZE;
wire [1:0] S_AXI_AWBURST;
wire [1:0] S_AXI_AWLOCK;
wire [3:0] S_AXI_AWCACHE;
wire [2:0] S_AXI_AWPROT;
wire [3:0] S_AXI_AWREGION;
wire [3:0] S_AXI_AWQOS;
wire [0:0] S_AXI_AWUSER;
wire S_AXI_AWVALID;
wire [0:0] S_AXI_WID;
wire [31:0] S_AXI_WDATA;
wire [3:0] S_AXI_WSTRB;
wire S_AXI_WLAST;
wire [0:0] S_AXI_WUSER;
wire S_AXI_WVALID;
wire S_AXI_BREADY;
wire [0:0] S_AXI_ARID;
wire [31:0] S_AXI_ARADDR;
wire [7:0] S_AXI_ARLEN;
wire [2:0] S_AXI_ARSIZE;
wire [1:0] S_AXI_ARBURST;
wire [1:0] S_AXI_ARLOCK;
wire [3:0] S_AXI_ARCACHE;
wire [2:0] S_AXI_ARPROT;
wire [3:0] S_AXI_ARREGION;
wire [3:0] S_AXI_ARQOS;
wire [0:0] S_AXI_ARUSER;
wire S_AXI_ARVALID;
wire S_AXI_RREADY;
wire pixclk;
// Outputs
wire S_AXI_AWREADY;
wire S_AXI_WREADY;
wire [0:0] S_AXI_BID;
wire [1:0] S_AXI_BRESP;
wire [0:0] S_AXI_BUSER;
wire S_AXI_BVALID;
wire S_AXI_ARREADY;
wire [0:0] S_AXI_RID;
wire [31:0] S_AXI_RDATA;
wire [1:0] S_AXI_RRESP;
wire S_AXI_RLAST;
wire [0:0] S_AXI_RUSER;
wire S_AXI_RVALID;
wire TMDS_tx_clk_p;
wire TMDS_tx_clk_n;
wire TMDS_tx_2_G_p;
wire TMDS_tx_2_G_n;
wire TMDS_tx_1_R_p;
wire TMDS_tx_1_R_n;
wire TMDS_tx_0_B_p;
wire TMDS_tx_0_B_n;
// Instantiate the Unit Under Test (UUT)
CDC_axi_slave uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY),
.pixclk(pixclk),
.TMDS_tx_clk_p(TMDS_tx_clk_p),
.TMDS_tx_clk_n(TMDS_tx_clk_n),
.TMDS_tx_2_G_p(TMDS_tx_2_G_p),
.TMDS_tx_2_G_n(TMDS_tx_2_G_n),
.TMDS_tx_1_R_p(TMDS_tx_1_R_p),
.TMDS_tx_1_R_n(TMDS_tx_1_R_n),
.TMDS_tx_0_B_p(TMDS_tx_0_B_p),
.TMDS_tx_0_B_n(TMDS_tx_0_B_n)
);
// clk_gen のインスタンス
clk_gen #(
.CLK_PERIOD(100), // 10nsec, 100MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) ACLKi (
.clk_out(ACLK)
);
clk_gen #(
.CLK_PERIOD(250), // 25nsec, 40MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) PIXCLKi (
.clk_out(pixclk)
);
// reset_gen のインスタンス
reset_gen #(
.RESET_STATE(1'b0),
.RESET_TIME(1000) // 100nsec
) RESETi (
.reset_out(ARESETN)
);
// AXI4_BFM のインスタンス
AXI4_Master_BFM #(.DELAY(DELAY)) MBFMi(
.ACLK(ACLK),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// OVL Checker
OVL_Checker OVLi (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// test
// Write Channel
// wr_data生成、+1する
reg [15:0] wcount;
wire [31:0] wdata;
always @(posedge ACLK) begin
if (~ARESETN)
wcount <= 0;
else begin
if (S_AXI_WVALID & S_AXI_WREADY)
wcount <= wcount + 16'd1;
end
end
assign wdata = {{16{1'b0}}, wcount};
reg WriteTaskBusy = 1'b0;
integer wt_cnt;
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
for (wt_cnt=0; wt_cnt<NUMBER_OF_TEST; wt_cnt=wt_cnt+1) begin
WriteTaskBusy = 1'b1;
MBFMi.AXI_Master_1Seq_Write(0, 32'h100, 8'd7, ASIZE_BT_4, ABURST_INCR, wdata, 0, 2);
MBFMi.AXI_Master_1Seq_Write(0, 32'h200, 8'd3, ASIZE_BT_4, ABURST_INCR, wdata, 1, 3);
MBFMi.AXI_Master_1Seq_Write(0, 32'h300, 8'd1, ASIZE_BT_4, ABURST_INCR, wdata, 1, 4);
MBFMi.AXI_Master_1Seq_Write(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR, wdata, 1, 5);
WriteTaskBusy = 1'b0;
while (ReadTestBusy) begin // Read 終了待ち
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
// Read Channel
reg ReadTestBusy = 1'b0;
integer rd_cnt;
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
for (rd_cnt=0; rd_cnt<NUMBER_OF_TEST; rd_cnt=rd_cnt+1) begin
ReadTestBusy = 1'b1;
#1000;
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Read(0, 32'h100, 8'd7, ASIZE_BT_4, ABURST_INCR, 2);
MBFMi.AXI_Master_1Seq_Read(0, 32'h200, 8'd3, ASIZE_BT_4, ABURST_INCR, 3);
MBFMi.AXI_Master_1Seq_Read(0, 32'h300, 8'd1, ASIZE_BT_4, ABURST_INCR, 4);
MBFMi.AXI_Master_1Seq_Read(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR, 5);
ReadTestBusy = 1'b0;
while (WriteTaskBusy) begin // Write の終了待ち
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
endmodule
module clk_gen #(
parameter CLK_PERIOD = 100,
parameter real CLK_DUTY_CYCLE = 0.5,
parameter CLK_OFFSET = 0,
parameter START_STATE = 1'b0 )
(
output reg clk_out
);
begin
initial begin
#CLK_OFFSET;
forever
begin
clk_out = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
end
endmodule
module reset_gen #(
parameter RESET_STATE = 1'b1,
parameter RESET_TIME = 100 )
(
output reg reset_out
);
begin
initial begin
reset_out = RESET_STATE;
#RESET_TIME;
reset_out = ~RESET_STATE;
end
end
endmodule
`default_nettype wire
-------------------------------------------------------------------------------
--
-- AXI Master
--
-- VHDL-Standard: VHDL'93
----------------------------------------------------------------------------
--
-- Structure:
-- char_write_axi_master
--
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
package m_seq_pack is
function M_SEQ24_F(mseq24in : std_logic_vector
)return std_logic_vector;
end package m_seq_pack;
package body m_seq_pack is
function M_SEQ24_F(mseq24in : std_logic_vector
)return std_logic_vector is
variable mseq24 : std_logic_vector(23 downto 0);
variable xor_result : std_logic;
begin
xor_result := mseq24in(23) xor mseq24in(3) xor mseq24in(2) xor mseq24in(0);
mseq24 := mseq24in(22 downto 0) & xor_result;
return mseq24;
end M_SEQ24_F;
end m_seq_pack;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
library work;
use work.m_seq_pack.all;
--library unisim;
--use unisim.vcomponents.all;
entity char_write_axi_master is
generic(
C_M_AXI_SUPPORTS_THREADS : integer := 0;
C_M_AXI_THREAD_ID_WIDTH : integer := 1;
C_M_AXI_ADDR_WIDTH : integer := 32;
C_M_AXI_DATA_WIDTH : integer := 64;
C_INTERCONNECT_M_AXI_WRITE_ISSUING : integer := 8;
C_INTERCONNECT_M_AXI_READ_ISSUING : integer := 8;
C_M_AXI_SUPPORTS_READ : integer := 0;
C_M_AXI_SUPPORTS_WRITE : integer := 1;
C_M_AXI_SUPPORTS_USER_SIGNALS : integer := 0;
C_M_AXI_AWUSER_WIDTH : integer := 1;
C_M_AXI_ARUSER_WIDTH : integer := 1;
C_M_AXI_WUSER_WIDTH : integer := 1;
C_M_AXI_RUSER_WIDTH : integer := 1;
C_M_AXI_BUSER_WIDTH : integer := 1;
C_M_AXI_SUPPORTS_NARROW_BURST : integer := 0;
C_M_AXI_TARGET : std_logic_vector(31 downto 0) := x"00000000";
C_M_AXI_BURST_LEN : integer := 16;
C_OFFSET_WIDTH : integer := 9;
DISP_INTERVAL_DIV : integer := 20000000 -- 0.2sec 間隔でキャラクタを書くための分周値
);
port(
-- System Signals
ACLK : in std_logic;
ARESETN : in std_logic;
-- Master Interface Write Address
M_AXI_AWID : out std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
M_AXI_AWADDR : out std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
M_AXI_AWLEN : out std_logic_vector(8-1 downto 0);
M_AXI_AWSIZE : out std_logic_vector(3-1 downto 0);
M_AXI_AWBURST : out std_logic_vector(2-1 downto 0);
M_AXI_AWLOCK : out std_logic;
M_AXI_AWCACHE : out std_logic_vector(4-1 downto 0);
M_AXI_AWPROT : out std_logic_vector(3-1 downto 0);
-- AXI3 M_AXI_AWREGION:out std_logic_vector(4-1 downto 0);
M_AXI_AWQOS : out std_logic_vector(4-1 downto 0);
M_AXI_AWUSER : out std_logic_vector(C_M_AXI_AWUSER_WIDTH-1 downto 0);
M_AXI_AWVALID : out std_logic;
M_AXI_AWREADY : in std_logic;
-- Master Interface Write Data
-- AXI3 M_AXI_WID(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
M_AXI_WDATA : out std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
M_AXI_WSTRB : out std_logic_vector(C_M_AXI_DATA_WIDTH/8-1 downto 0);
M_AXI_WLAST : out std_logic;
M_AXI_WUSER : out std_logic_vector(C_M_AXI_WUSER_WIDTH-1 downto 0);
M_AXI_WVALID : out std_logic;
M_AXI_WREADY : in std_logic;
-- Master Interface Write Response
M_AXI_BID : in std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
M_AXI_BRESP : in std_logic_vector(2-1 downto 0);
M_AXI_BUSER : in std_logic_vector(C_M_AXI_BUSER_WIDTH-1 downto 0);
M_AXI_BVALID : in std_logic;
M_AXI_BREADY : out std_logic;
-- Master Interface Read Address
M_AXI_ARID : out std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
M_AXI_ARADDR : out std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
M_AXI_ARLEN : out std_logic_vector(8-1 downto 0);
M_AXI_ARSIZE : out std_logic_vector(3-1 downto 0);
M_AXI_ARBURST : out std_logic_vector(2-1 downto 0);
M_AXI_ARLOCK : out std_logic_vector(2-1 downto 0);
M_AXI_ARCACHE : out std_logic_vector(4-1 downto 0);
M_AXI_ARPROT : out std_logic_vector(3-1 downto 0);
-- AXI3 M_AXI_ARREGION:out std_logic_vector(4-1 downto 0);
M_AXI_ARQOS : out std_logic_vector(4-1 downto 0);
M_AXI_ARUSER : out std_logic_vector(C_M_AXI_ARUSER_WIDTH-1 downto 0);
M_AXI_ARVALID : out std_logic;
M_AXI_ARREADY : in std_logic;
-- Master Interface Read Data
M_AXI_RID : in std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
M_AXI_RDATA : in std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
M_AXI_RRESP : in std_logic_vector(2-1 downto 0);
M_AXI_RLAST : in std_logic;
M_AXI_RUSER : in std_logic_vector(C_M_AXI_RUSER_WIDTH-1 downto 0);
M_AXI_RVALID : in std_logic;
M_AXI_RREADY : out std_logic;
init_done : in std_logic;
-- Example Design only
wr_error : out std_logic;
rd_error : out std_logic
);
end char_write_axi_master;
-------------------------------------------------------------------------------
-- Architecture
-------------------------------------------------------------------------------
architecture implementation of char_write_axi_master is
constant RESP_OKAY : std_logic_vector := "00";
constant RESP_EXOKAY : std_logic_vector := "01";
constant RESP_SLVERR : std_logic_vector := "10";
constant RESP_DECERR : std_logic_vector := "11";
constant DDR3_START_ADDR : std_logic_vector := x"10000000";
constant ROW_ALL_PIXELS : integer := 640;
constant COULMN_ALL_PIXELS : integer := 480;
constant SVGA_ADDR_LIMIT : integer := ROW_ALL_PIXELS*COULMN_ALL_PIXELS*4; -- SVGAのアドレスリミット(横ピクセル数 * 縦ピクセル数 * 1ピクセルを表すバイト数)
signal reset_1d, reset_2d, reset : std_logic;
type wr_main_transaction_state is (idle_wr_main, char_bitmap_trans_start, char_bitmap_trans_wait, write_state, wait_state);
signal wr_main_cs, wr_main_1d : wr_main_transaction_state;
type write_transaction_state is (idle_wr, awvalid_assert, data_write_hold, bready_assert, wr_tran_end);
signal wrt_cs : write_transaction_state;
type write_wvalid_state is (idle_wvalid, wvalid_assert, wvalid_hold);
signal wrt_wv_cs : write_wvalid_state;
signal awvalid, wvalid, bready : std_logic;
signal wr_addr, wr_addr_old, wr_addr_sc : std_logic_vector(31 downto 0);
signal awlen, write_count : std_logic_vector(7 downto 0);
signal wlast : std_logic;
signal disp_count : integer;
signal disp_ena : std_logic;
signal wr_tran_count : std_logic_vector(2 downto 0);
signal char_code : std_logic_vector(6 downto 0);
signal color_code : std_logic_vector(31 downto 0);
signal char_code_ena : std_logic;
signal raster_data : std_logic_vector(63 downto 0);
signal raster_valid : std_logic;
signal raster_ready : std_logic;
signal fifo_empty : std_logic;
component char_gen_8raster
port(
clk : in std_logic;
reset : in std_logic;
char_code : in std_logic_vector(6 downto 0);
color_code : in std_logic_vector(31 downto 0);
char_code_ena : in std_logic; -- アスキーキャラクタコードのイネーブル、1パルス
raster_valid : out std_logic; -- ラスタデータのRead時のReady信号
raster_data : out std_logic_vector(63 downto 0);
raster_ready : in std_logic;
fifo_empty : out std_logic
);
end component;
begin
-- ARESETN をACLK で同期化
process (ACLK) begin
if ACLK'event and ACLK='1' then
reset_1d <= not ARESETN or not init_done;
reset_2d <= reset_1d;
end if;
end process;
reset <= reset_2d;
-- インプリメントでは0.2秒に1回表示する
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
disp_count <= 0;
disp_ena <= '0';
else
if disp_count = DISP_INTERVAL_DIV then
disp_count <= 0;
disp_ena <= '1';
else
disp_count <= disp_count + 1;
disp_ena <= '0';
end if;
end if;
end if;
end process;
-- Write Transaction State Machine
-- Writeを0.2秒に1回行う。Readは無し
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_main_cs <= idle_wr_main;
char_code_ena <= '0';
else
case (wr_main_cs) is
when idle_wr_main =>
wr_main_cs <= char_bitmap_trans_start;
when char_bitmap_trans_start => -- キャラクタコードからビットマップデータへの変換をスタート
char_code_ena <= '1';
wr_main_cs <= char_bitmap_trans_wait;
when char_bitmap_trans_wait => -- キャラクタコードからビットマップデータへの変換が終了するまでWait
char_code_ena <= '0';
if raster_valid='1' then
wr_main_cs <= write_state;
end if;
when write_state =>
if wrt_cs = wr_tran_end and wr_tran_count=7 then -- 1キャラクタ描画終了
wr_main_cs <= wait_state;
end if;
when wait_state =>
if disp_ena='1' then
wr_main_cs <= idle_wr_main;
end if;
end case;
end if;
end if;
end process;
-- writeの数を数える
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_tran_count <= (others => '0');
else
if wrt_cs = wr_tran_end then
wr_tran_count <= wr_tran_count + 1;
elsif wr_main_cs = wait_state then
wr_tran_count <= (others => '0');
end if;
end if;
end if;
end process;
-- color_code の処理
color_code(31 downto 24) <= (others => '0');
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
color_code(23 downto 0) <= (others => '1');
else
if wr_main_cs=write_state and wrt_cs = wr_tran_end and wr_tran_count=7 then -- 1キャラクタ描画終了
color_code(23 downto 0) <= M_SEQ24_F(color_code(23 downto 0));
end if;
end if;
end if;
end process;
-- color_code(23 downto 0) <= (others => '1');
char_gen_8raster_i : char_gen_8raster port map(
clk => ACLK,
reset => reset,
char_code => char_code,
color_code => color_code,
char_code_ena => char_code_ena,
raster_valid => raster_valid,
raster_data => raster_data,
raster_ready => raster_ready,
fifo_empty => fifo_empty
);
-- Write
M_AXI_AWID <= "0";
M_AXI_AWSIZE <= "011"; -- 8 bytes fixed
M_AXI_AWBURST <= "01"; -- INCR
M_AXI_AWLOCK <= '0'; -- Normal Access
M_AXI_AWCACHE <= "0010"; -- Normal Non-cacheable Non-bufferable
-- M_AXI_AWCACHE <= "0011"; -- Normal Non-cacheable Bufferable, Zynq-7020ではBRESPが10でSLVERRになってしまい設定してはならない。
M_AXI_AWPROT <= "000"; -- Data access, Secure access, Unprivileged access
M_AXI_AWQOS <= "0000"; -- default
M_AXI_AWUSER <= "0";
M_AXI_WSTRB <= (others => '1');
M_AXI_WUSER <= "0";
M_AXI_AWLEN <= CONV_STD_LOGIC_VECTOR(3, 8); -- 1ライン8ピクセル-1(64ビット幅なので4バースト)
awlen <= CONV_STD_LOGIC_VECTOR(3, 8); -- 1ライン8ピクセル-1(64ビット幅なので4バースト)
-- AXI4バス Write Transaction State Machine
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wrt_cs <= idle_wr;
awvalid <= '0';
bready <= '0';
else
case(wrt_cs) is
when idle_wr =>
if wr_main_cs = write_state then
wrt_cs <= awvalid_assert;
awvalid <= '1';
end if;
when awvalid_assert =>
if M_AXI_AWREADY='1' then
if wrt_wv_cs=wvalid_hold or (wrt_wv_cs=wvalid_assert and write_count=0 and M_AXI_WREADY='1') then
wrt_cs <= bready_assert;
bready <= '1';
else
wrt_cs <= data_write_hold;
end if;
awvalid <= '0';
end if;
when data_write_hold =>
if wrt_wv_cs=wvalid_hold or (wrt_wv_cs=wvalid_assert and write_count=0 and M_AXI_WREADY='1') then
wrt_cs <= bready_assert;
bready <= '1';
end if;
when bready_assert =>
if M_AXI_BVALID='1' then
wrt_cs <= wr_tran_end;
bready <= '0';
end if;
when wr_tran_end =>
wrt_cs <= idle_wr;
end case;
end if;
end if;
end process;
-- AXI4 バス Write Transaction WVALID State Machine
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wrt_wv_cs <= idle_wvalid;
wvalid <= '0';
else
case(wrt_wv_cs) is
when idle_wvalid =>
if wrt_cs=awvalid_assert then
wrt_wv_cs <= wvalid_assert;
wvalid <= '1';
end if;
when wvalid_assert =>
if write_count=0 and M_AXI_WREADY='1' then -- 終了
wrt_wv_cs <= wvalid_hold;
wvalid <= '0';
end if;
when wvalid_hold =>
if wrt_cs=bready_assert then
wrt_wv_cs <= idle_wvalid;
end if;
end case;
end if;
end if;
end process;
M_AXI_AWVALID <= awvalid;
M_AXI_WVALID <= wvalid;
M_AXI_BREADY <= bready;
-- wr_addr の処理、Write Transaction が終了するたびにキャラクタの下のラインをアドレスするために640を足す。
-- wr_addr_old : キャラクタのベースアドレス(左上)、wr_add_sc : キャラクタの1行の左上のアドレス
-- 1キャラクタ=4バイと、よってアドレスは*4
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_addr <= DDR3_START_ADDR;
wr_addr_old <= DDR3_START_ADDR;
wr_addr_sc <= DDR3_START_ADDR;
else
if wrt_cs = wr_tran_end then
if wr_tran_count=7 then -- 1キャラクタ描画終了
if wr_addr_old >= DDR3_START_ADDR+(SVGA_ADDR_LIMIT-(ROW_ALL_PIXELS*4*8)+(ROW_ALL_PIXELS-8)*4) then -- 1画面描画終了, 640*4*(480-8)+(640-8)*4、1キャラクタは8行なので、総数ピクセルから8行分のピクセルを除いて、最後のキャラクタまでのピクセルを足す
wr_addr <= DDR3_START_ADDR;
wr_addr_old <= DDR3_START_ADDR;
wr_addr_sc <= DDR3_START_ADDR;
elsif (wr_addr_sc+(ROW_ALL_PIXELS-8)*4) - wr_addr_old > 0 then -- 次の行に行かない場合
wr_addr <= wr_addr_old + 8*4; -- 次のキャラクタのアドレス
wr_addr_old <= wr_addr_old + 8*4;
else -- 1行キャラクタを書き終わったので、次のキャラクタ行に移動する
wr_addr <= wr_addr_sc + ROW_ALL_PIXELS *8 *4; -- x8行 x4バイト
wr_addr_old <= wr_addr_sc + ROW_ALL_PIXELS *8 * 4;
wr_addr_sc <= wr_addr_sc + ROW_ALL_PIXELS *8 * 4;
end if;
else -- 同一キャラクタの次の行を描画
wr_addr <= wr_addr + ROW_ALL_PIXELS*4;
end if;
end if;
end if;
end if;
end process;
M_AXI_AWADDR <= wr_addr;
-- write_data の処理、char_gen_8raster のFIFOからデータを出力する
raster_ready <= '1' when wvalid='1' and M_AXI_WREADY='1' else '0';
M_AXI_WDATA <= raster_data;
-- write_count の処理
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
write_count <= (others => '0');
else
if wrt_wv_cs=idle_wvalid then
write_count <= awlen;
elsif wrt_wv_cs=wvalid_assert and M_AXI_WREADY='1' then
write_count <= write_count - 1;
end if;
end if;
end if;
end process;
-- wlastの処理
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wlast <= '0';
else
if wrt_wv_cs=idle_wvalid and awlen=0 then -- awlen が0の時はデータ転送の最初からwlast をアサートする
wlast <= '1';
elsif wrt_wv_cs=wvalid_assert and write_count=1 and M_AXI_WREADY='1' then -- awlen が0で無い時はwrite_count が1でM_AXI_WREADY='1'の時、つまりwrite_count が0の時にwlastをアサートする
wlast <= '1';
elsif wrt_wv_cs=wvalid_assert and write_count=0 and M_AXI_WREADY='1' then -- データ転送が終了なのでwlast を0にする
wlast <= '0';
end if;
end if;
end if;
end process;
M_AXI_WLAST <= wlast;
-- wr_error の処理、M_AXI_BRESPがRESP_OKAY以外の時にwr_errorを点灯する
process(ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_error <= '0';
else
if wrt_cs=bready_assert and M_AXI_BVALID='1' and M_AXI_BRESP/=RESP_OKAY then
wr_error <= '1';
end if;
end if;
end if;
end process;
-- char_code の処理
process(ACLK) begin -- キャラクタコードを+1して表示
if ACLK'event and ACLK='1' then
if reset='1' then
char_code <= "0100001"; -- キャラクタの!
else
if wrt_cs = wr_tran_end and wr_tran_count=7 then -- 1キャラクタ描画終了
if char_code="1111110" then -- キャラクタの~
char_code <= "0100001"; -- キャラクタの!
else
char_code <= char_code + 1;
end if;
end if;
end if;
end if;
end process;
-- Readは無し
M_AXI_ARID <= "0";
M_AXI_ARLEN <= (others => '0');
M_AXI_ARSIZE <= "010"; -- 4bytes
M_AXI_ARBURST <= "01"; -- INCR
M_AXI_ARLOCK <= "00"; -- Normal Access
M_AXI_ARCACHE <= "0010"; -- Normal Non-cacheable Non-bufferable
M_AXI_ARPROT <= "000"; -- Data access, Secure access, Unprivileged access
M_AXI_ARQOS <= "0000"; -- default
M_AXI_ARUSER <= "0";
M_AXI_ARADDR <= (others => '0');
M_AXI_ARVALID <= '0';
M_AXI_RREADY <= '0';
rd_error <= '0';
end implementation;
// キャラクタコードのラスタデータ出力
//
// char_code_ena 1パルスでFIFOにキャラクタコードのラスタデータを読み込む
// すべてのラスタデータを読み込めたら、raster_validが立つ
// 上位モジュールは、ラスタデータを1つ読み終えたら、 raster_ready を立てる
//
`default_nettype none
module char_gen_8raster (
input wire clk,
input wire reset,
input wire [6:0] char_code, // アスキーキャラクタコード
input wire [31:0] color_code, // カラーコード
input wire char_code_ena, // アスキーキャラクタコードのイネーブル、1パルス
output reg raster_valid, // ラスタデータ有効(1パルス)
output wire [63:0] raster_data, // ラスタデータ
input wire raster_ready, // ラスタデータのRead時のReady信号
output wire fifo_empty
);
parameter [2:0] IDLE_MAIN = 3'b000,
CHAR_ROM_READ = 3'b001,
CHAR_ROM_VALID = 3'b011,
CONVERT_FORMAT = 3'b010,
NEXT_LINE_ST = 3'b110,
RASTER_VALID_WAIT = 3'b111,
RASTER_VALID_ST = 3'b101;
reg [2:0] mainsm_cs;
reg [7:0] char_shift_reg;
reg [6:0] char_code_hold;
reg [31:0] color_code_hold;
reg [2:0] shift_count;
reg [2:0] row_count;
reg [31:0] bitmap_pixel_data;
wire cgfifo_wr_en;
wire cgfifo_full;
wire cgfifo_underflow;
wire [5:0] cgfifo_data_count;
wire [7:0] char_raster_8bit;
// キャラクタ・ジェネレータROMのインスタンス
char_gen_rom char_gen_rom_inst (
.clk(clk),
.reset(reset),
.char_addr(char_code_hold),
.row_addr(row_count),
.dout(char_raster_8bit)
);
// char_code, color_code をラッチする
always @(posedge clk) begin
if (reset) begin
char_code_hold <= 0;
color_code_hold <= 0;
end else begin
if (mainsm_cs == IDLE_MAIN && char_code_ena) begin
char_code_hold <= char_code;
color_code_hold <= color_code;
end
end
end
// main state machine
always @(posedge clk) begin
if (reset) begin
mainsm_cs <= IDLE_MAIN;
raster_valid <= 1'b0;
end else begin
case (mainsm_cs)
IDLE_MAIN : begin // char_code_ena が1になるとスタート, 0
raster_valid <= 1'b0;
if (char_code_ena) // キャラクタのラスタ・ビットマップからRGBビットマップへの変換スタート
mainsm_cs <= CHAR_ROM_READ;
end
CHAR_ROM_READ : // char_gen_rom のReadのために1クロックWaitする, 1
mainsm_cs <= CHAR_ROM_VALID;
CHAR_ROM_VALID : // この時点で、 char_gen_rom のdoutが確定される, 3
mainsm_cs <= CONVERT_FORMAT;
CONVERT_FORMAT : // キャラクタのラスタ・ビットマップからRGBビットマップへの変換(1ラスタ分), 2
if (shift_count == 0) begin
if (row_count == 7) // 8ラスタを終了
mainsm_cs <= RASTER_VALID_WAIT;
else // 次のラスタへ
mainsm_cs <= NEXT_LINE_ST;
end
NEXT_LINE_ST : // 次のラスタへの準備, 6
mainsm_cs <= CHAR_ROM_READ;
RASTER_VALID_WAIT : // 1キャラクタ分の変換が終了, char_gen_fifo が32になるまで待機, 7
if (cgfifo_data_count >= 32)
mainsm_cs <= RASTER_VALID_ST;
RASTER_VALID_ST : begin // キャラクタがすべてchar_gen_fifo に入ったので、AXIトランザクション開始, 5
raster_valid <= 1'b1;
mainsm_cs <= IDLE_MAIN;
end
endcase
end
end
// char_gen_rom の出力データ用シフトレジスタ
always @(posedge clk) begin
if (reset)
char_shift_reg <= 0;
else begin
if (mainsm_cs == CHAR_ROM_VALID)
char_shift_reg <= char_raster_8bit[7:0];
else if (mainsm_cs == CONVERT_FORMAT)
char_shift_reg <= {1'b0, char_shift_reg[7:1]};
end
end
// ピクセルのシフト数のカウント
always @(posedge clk) begin
if (reset)
shift_count <= 3'd7;
else begin
if (mainsm_cs == CONVERT_FORMAT && shift_count != 0)
shift_count <= shift_count - 3'd1;
else if (mainsm_cs == NEXT_LINE_ST || mainsm_cs == RASTER_VALID_ST)
shift_count <= 3'd7;
end
end
// row_count
always @(posedge clk) begin
if (reset)
row_count <= 3'd0;
else begin
if (mainsm_cs == NEXT_LINE_ST && row_count != 7)
row_count <= row_count + 3'd1;
else if (mainsm_cs == IDLE_MAIN)
row_count <= 3'd0;
end
end
// char_gen_fifo へのデータの入力
always @* begin
if (char_shift_reg[0])
bitmap_pixel_data <= color_code_hold;
else
bitmap_pixel_data <= 0;
end
assign cgfifo_wr_en = (mainsm_cs == CONVERT_FORMAT) ? 1'b1 : 1'b0;
// char_gen_fifo のインスタンス
char_gen_fifo char_gen_fifo_inst (
.rst(reset), // input rst
.wr_clk(clk), // input wr_clk
.rd_clk(clk), // input rd_clk
.din(bitmap_pixel_data), // input [31 : 0] din
.wr_en(cgfifo_wr_en), // input wr_en
.rd_en(raster_ready), // input rd_en
.dout(raster_data), // output [63 : 0] dout
.full(cgfifo_full), // output full
.empty(fifo_empty), // output empty
.underflow(cgfifo_underflow), // output underflow
.rd_data_count(cgfifo_data_count) // output [5 : 0] rd_data_count
);
endmodule
##############################################################
#
# Xilinx Core Generator version 14.2
# Date: Sat Oct 13 07:46:30 2012
#
##############################################################
#
# This file contains the customisation parameters for a
# Xilinx CORE Generator IP GUI. It is strongly recommended
# that you do not manually alter this file as it may cause
# unexpected and unsupported behavior.
#
##############################################################
#
# Generated from component: xilinx.com:ip:fifo_generator:9.2
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = Verilog
SET device = xc7z020
SET devicefamily = zynq
SET flowvendor = Other
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = clg484
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -1
SET verilogsim = true
SET vhdlsim = false
# END Project Options
# BEGIN Select
SELECT Fifo_Generator xilinx.com:ip:fifo_generator:9.2
# END Select
# BEGIN Parameters
CSET add_ngc_constraint_axi=false
CSET almost_empty_flag=false
CSET almost_full_flag=false
CSET aruser_width=1
CSET awuser_width=1
CSET axi_address_width=32
CSET axi_data_width=64
CSET axi_type=AXI4_Stream
CSET axis_type=FIFO
CSET buser_width=1
CSET clock_enable_type=Slave_Interface_Clock_Enable
CSET clock_type_axi=Common_Clock
CSET component_name=char_gen_fifo
CSET data_count=false
CSET data_count_width=6
CSET disable_timing_violations=false
CSET disable_timing_violations_axi=false
CSET dout_reset_value=0
CSET empty_threshold_assert_value=4
CSET empty_threshold_assert_value_axis=1022
CSET empty_threshold_assert_value_rach=1022
CSET empty_threshold_assert_value_rdch=1022
CSET empty_threshold_assert_value_wach=1022
CSET empty_threshold_assert_value_wdch=1022
CSET empty_threshold_assert_value_wrch=1022
CSET empty_threshold_negate_value=5
CSET enable_aruser=false
CSET enable_awuser=false
CSET enable_buser=false
CSET enable_common_overflow=false
CSET enable_common_underflow=false
CSET enable_data_counts_axis=false
CSET enable_data_counts_rach=false
CSET enable_data_counts_rdch=false
CSET enable_data_counts_wach=false
CSET enable_data_counts_wdch=false
CSET enable_data_counts_wrch=false
CSET enable_ecc=false
CSET enable_ecc_axis=false
CSET enable_ecc_rach=false
CSET enable_ecc_rdch=false
CSET enable_ecc_wach=false
CSET enable_ecc_wdch=false
CSET enable_ecc_wrch=false
CSET enable_read_channel=false
CSET enable_read_pointer_increment_by2=false
CSET enable_reset_synchronization=true
CSET enable_ruser=false
CSET enable_tdata=false
CSET enable_tdest=false
CSET enable_tid=false
CSET enable_tkeep=false
CSET enable_tlast=false
CSET enable_tready=true
CSET enable_tstrobe=false
CSET enable_tuser=false
CSET enable_write_channel=false
CSET enable_wuser=false
CSET fifo_application_type_axis=Data_FIFO
CSET fifo_application_type_rach=Data_FIFO
CSET fifo_application_type_rdch=Data_FIFO
CSET fifo_application_type_wach=Data_FIFO
CSET fifo_application_type_wdch=Data_FIFO
CSET fifo_application_type_wrch=Data_FIFO
CSET fifo_implementation=Independent_Clocks_Block_RAM
CSET fifo_implementation_axis=Common_Clock_Block_RAM
CSET fifo_implementation_rach=Common_Clock_Block_RAM
CSET fifo_implementation_rdch=Common_Clock_Block_RAM
CSET fifo_implementation_wach=Common_Clock_Block_RAM
CSET fifo_implementation_wdch=Common_Clock_Block_RAM
CSET fifo_implementation_wrch=Common_Clock_Block_RAM
CSET full_flags_reset_value=1
CSET full_threshold_assert_value=63
CSET full_threshold_assert_value_axis=1023
CSET full_threshold_assert_value_rach=1023
CSET full_threshold_assert_value_rdch=1023
CSET full_threshold_assert_value_wach=1023
CSET full_threshold_assert_value_wdch=1023
CSET full_threshold_assert_value_wrch=1023
CSET full_threshold_negate_value=62
CSET id_width=4
CSET inject_dbit_error=false
CSET inject_dbit_error_axis=false
CSET inject_dbit_error_rach=false
CSET inject_dbit_error_rdch=false
CSET inject_dbit_error_wach=false
CSET inject_dbit_error_wdch=false
CSET inject_dbit_error_wrch=false
CSET inject_sbit_error=false
CSET inject_sbit_error_axis=false
CSET inject_sbit_error_rach=false
CSET inject_sbit_error_rdch=false
CSET inject_sbit_error_wach=false
CSET inject_sbit_error_wdch=false
CSET inject_sbit_error_wrch=false
CSET input_data_width=32
CSET input_depth=64
CSET input_depth_axis=1024
CSET input_depth_rach=16
CSET input_depth_rdch=1024
CSET input_depth_wach=16
CSET input_depth_wdch=1024
CSET input_depth_wrch=16
CSET interface_type=Native
CSET output_data_width=64
CSET output_depth=32
CSET overflow_flag=false
CSET overflow_flag_axi=false
CSET overflow_sense=Active_High
CSET overflow_sense_axi=Active_High
CSET performance_options=First_Word_Fall_Through
CSET programmable_empty_type=No_Programmable_Empty_Threshold
CSET programmable_empty_type_axis=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rach=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rdch=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wach=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wdch=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wrch=No_Programmable_Empty_Threshold
CSET programmable_full_type=No_Programmable_Full_Threshold
CSET programmable_full_type_axis=No_Programmable_Full_Threshold
CSET programmable_full_type_rach=No_Programmable_Full_Threshold
CSET programmable_full_type_rdch=No_Programmable_Full_Threshold
CSET programmable_full_type_wach=No_Programmable_Full_Threshold
CSET programmable_full_type_wdch=No_Programmable_Full_Threshold
CSET programmable_full_type_wrch=No_Programmable_Full_Threshold
CSET rach_type=FIFO
CSET rdch_type=FIFO
CSET read_clock_frequency=1
CSET read_data_count=true
CSET read_data_count_width=6
CSET register_slice_mode_axis=Fully_Registered
CSET register_slice_mode_rach=Fully_Registered
CSET register_slice_mode_rdch=Fully_Registered
CSET register_slice_mode_wach=Fully_Registered
CSET register_slice_mode_wdch=Fully_Registered
CSET register_slice_mode_wrch=Fully_Registered
CSET reset_pin=true
CSET reset_type=Asynchronous_Reset
CSET ruser_width=1
CSET synchronization_stages=2
CSET synchronization_stages_axi=2
CSET tdata_width=64
CSET tdest_width=4
CSET tid_width=8
CSET tkeep_width=4
CSET tstrb_width=4
CSET tuser_width=4
CSET underflow_flag=true
CSET underflow_flag_axi=false
CSET underflow_sense=Active_High
CSET underflow_sense_axi=Active_High
CSET use_clock_enable=false
CSET use_dout_reset=true
CSET use_embedded_registers=false
CSET use_extra_logic=true
CSET valid_flag=false
CSET valid_sense=Active_High
CSET wach_type=FIFO
CSET wdch_type=FIFO
CSET wrch_type=FIFO
CSET write_acknowledge_flag=false
CSET write_acknowledge_sense=Active_High
CSET write_clock_frequency=1
CSET write_data_count=false
CSET write_data_count_width=7
CSET wuser_width=1
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2012-06-23T13:35:37Z
# END Extra information
GENERATE
# CRC: a331f18e
// キャラクタジェネレータ用ROM
`default_nettype none
`timescale 1ns / 1ps
module char_gen_rom(clk, reset, char_addr, row_addr, dout);
input clk;
input reset;
input [6:0] char_addr;
input [2:0] row_addr;
output [7:0] dout;
wire clk;
wire reset;
wire [6:0] char_addr;
wire [2:0] row_addr;
wire [7:0] dout;
wire [10:0] addr;
assign addr = {1'b0, char_addr, row_addr};
RAMB16_S9 #(
.INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_08(256'h0014147F147F1414000000000012243600080008080808080000000000000000), // #,",!,
.INIT_09(256'h0000000000081018004C322254081408002152240812254200083E483E093E08), // ',&,%,$
.INIT_0A(256'h000808087F08080800492A1C7F1C2A4900040810101008040020100808081020), // +,*,),(
.INIT_0B(256'h00010204081020400006060000000000000000007F0000000002040600000000), // /,.,-,,
.INIT_0C(256'h001C22201820221C003E02041820221C001C080808080C080018244242422418), // 3,2,1,0
.INIT_0D(256'h001010202040407E003C42423E02423C001E20201E02023E0020207E22242830), // 7,6,5,4
.INIT_0E(256'h0004080C00000C000000000C00000C00003C42407C42423C003C42423C42423C), // ;,:,9,8
.INIT_0F(256'h000800081020221C00040810201008040000003E003E00000020100804081020), // ?,>,=,<
.INIT_10(256'h001C22010101221C003F41413F41413F0041417F2236141C005C2A155549221E), // C,B,A,@
.INIT_11(256'h001C22710101221C000101013F01017F007F01013F01017F001F21414141211F), // G,F,E,D
.INIT_12(256'h0022120A060A1222000E11101010103E001C08080808081C004141417F414141), // K,J,I,H
.INIT_13(256'h001C22414141221C00416151494543410041414149556341003E020202020202),// O,N,M,L
.INIT_14(256'h003C42403C02423C002111093F41413F005C26594141221C000101013F41413F), // S,R,Q,P
.INIT_15(256'h00225555554949490008141422224141001C224141414141000808080808087F), // W,V,U,T
.INIT_16(256'h0038080808080838003F02040810203F00080808081422410041221408142241), // [,Z,Y,X
.INIT_17(256'h007F0000000000000000000000221408001C10101010101C0008083E083E1422), // _,^,],\
.INIT_18(256'h0038040438000000001E22221E020200003C223C201C00000000000000180810), // c,b,a,`
.INIT_19(256'h001C221C0C122C00000808081C081000001C021E221C0000003C22223C202000), // g,f,e,d
.INIT_1A(256'h0024140C14240400000C1210100010000008080800080000002424241C040400), // k,j,i,h
.INIT_1B(256'h0018242424180000002828282814000000545454542A00000018080808080800), // o,n,m,l
.INIT_1C(256'h0018201804180000000404040C34000000202038243800000004041C241C0000), // s,r,q,p
.INIT_1D(256'h00142A2A2A2200000008141422220000001824242424000000180808081C0800), // w,v,u,t
.INIT_1E(256'h001008080C080810003E0408103E000000020408142200000022140814220000), // {,z,y,x
.INIT_1F(256'h0000000000000000000000000000142800040808180808040008080808080808), // ,~,},|
.INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
.INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000)
) CHAR_GEN_ROM_INST (
.DO(dout),
.DOP(),
.ADDR(addr),
.CLK(clk),
.DI(8'd0),
.DIP(1'b0),
.EN(1'b1),
.SSR(reset),
.WE(1'b0)
);
endmodule
type write_transaction_state is (idle_wr, awvalid_assert, data_write, bready_assert, wr_tran_end);
signal wrt_cs : write_transaction_state;
Optimizing FSM <FSM_1> on signal <wrt_cs[1:3]> with user encoding.
----------------------------
State | Encoding
----------------------------
idle_wr | 000
awvalid_assert | 001
data_write | 010
bready_assert | 011
wr_tran_end | 100
----------------------------
#Optimizing FSM
on signal with user encoding.
@DEFAULT_TOKEN=ERROR
idle_wr=000\b
awvalid_assert=001\b
data_write=010\b
bready_assert=011\b
wr_tran_end=100\b
parameter [2:0] IDLE_MAIN = 3'b000,
CHAR_ROM_READ = 3'b001,
CHAR_ROM_VALID = 3'b011,
CONVERT_FORMAT = 3'b010,
NEXT_LINE_ST = 3'b110,
RASTER_VALID_WAIT = 3'b111,
RASTER_VALID_ST = 3'b101;
reg [2:0] mainsm_cs;
Optimizing FSM <char_gen_8raster_i/FSM_2> on signal <mainsm_cs[1:3]> with user encoding.
-------------------
State | Encoding
-------------------
000 | 000
001 | 001
011 | 011
110 | 110
111 | 111
010 | 010
101 | 101
-------------------
#Optimizing FSM
on signal with user encoding.
@DEFAULT_TOKEN=ERROR
IDLE_MAIN=000\b
CHAR_ROM_READ=001\b
CHAR_ROM_VALID=011\b
CONVERT_FORMAT=010\b
NEXT_LINE_ST=110\b
RASTER_VALID_WAIT=111\b
RASTER_VALID_ST=101\b
(pcb H:\EDA\KiCad\Work\acrylic_sign\acrylic_sign.dsn
(parser
(string_quote ")
(space_in_quoted_tokens on)
(host_cad "KiCad's Pcbnew")
(host_version "(2012-jul-04-ja)-stable")
)
(resolution mil 10)
(unit mil)
(structure
(layer 表面
(type signal)
(property
(index 0)
)
)
(layer 裏面
(type signal)
(property
(index 1)
)
)
1.Segwayの電源をONする。(電源スイッチ長押し)
2.ハンドルを普通に握って片足を乗せる。(ここでバランサーがONになるみたいです)
3.ハンドルの棒の天辺とその下を手で握って、真っ直ぐ前を見ながら乗る。
・0.2秒に1回、1つのキャラクタをビットマップ・ディスプレイ・コントローラ上に描画する。
・キャラクタの色は0を除いた7色とする。(2012/10/14変更)キャラクタの色は、24ビットのM系列で決定されるカラーコードを使用する。
・バースト可能な水平8ピクセル分を64ビットバス幅4バーストでフレームバッファ用DDR3 SDRAMにWriteする。これがキャラクタの1ラインとなる。
・アドレスを計算しながら、キャラクタの8ラインを描画する。
・次は色を変えて、次のキャラクタを描画する。
・キャラクタコードは0x20から0x7F までとする。
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | 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 | - | - | - |