// parameter_test.v
module parameter_test # (
parameter RESOLUTION = "VGA"
)(
output wire [10:0] param_out
);
parameter integer H_ACTIVE_VIDEO = (RESOLUTION=="VGA") ? 640 :
(RESOLUTION=="SVGA") ? 800 :
(RESOLUTION=="XGA") ? 1024 :
(RESOLUTION=="SXGA") ? 1280 :
(RESOLUTION=="HD") ? 1920 : 1920;
assign param_out = H_ACTIVE_VIDEO;
endmodule
にしてみました。parameter RESOLUTION = "XGA"
1.system_top_tbがシミュレーションのテストベンチで最上位ということになる。
2.その下に、system_topを uut してインスタンスしてある。
3.systemという名前のXPSプロジェクトが、system_i という名前でインスタンスしてある。
4.XPSプロジェクトに下に、 mem_sim_axi_slave_0をインスタンスしてある。
5.mem_sim_axi_slaveでは、memory_8bit を memory_8bit_i というインスタンス名で generate 文でインスタンスしてある。
// instance memory_8bit
generate
genvar i;
for (i=(C_S_AXI_DATA_WIDTH/8-1); i>=0; i=i-1) begin : MEMORY_GEN
memory_8bit #(
.C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH),
.C_MEMORY_SIZE(C_MEMORY_SIZE)
) memory_8bit_i (
.clk(ACLK),
.waddr(waddr),
.write_data(S_AXI_WDATA[i*8+7:i*8]),
.write_enable(wready & S_AXI_WVALID),
.byte_enable(S_AXI_WSTRB[i]),
.raddr(raddr),
.read_data(S_AXI_RDATA[i*8+7:i*8])
);
end
endgenerate
// R, G, B 毎に違った生成多項式のM系列を用意した
function [7:0] mseqf8_R (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
mseqf8_R = {din[6:0], xor_result};
end
endfunction
function [7:0] mseqf8_G (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[4] ^ din[2] ^ din[0];
mseqf8_G = {din[6:0], xor_result};
end
endfunction
function [7:0] mseqf8_B (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[5] ^ din[2] ^ din[1];
mseqf8_B = {din[6:0], xor_result};
end
endfunction
// M系列を使用した擬似ランダム数でメモリの半分を初期化した
initial begin : memory_init_zero
integer i;
for (i=0; i<480000; i=i+1) begin
uut.system_i.mem_sim_axi_slave_0.mem_sim_axi_slave_0.MEMORY_GEN[3].memory_8bit_i.mem[i] = 8'd0;
end
end
initial begin : memory_init_red
integer i;
for (i=0; i<480000; i=i+1) begin
uut.system_i.mem_sim_axi_slave_0.mem_sim_axi_slave_0.MEMORY_GEN[2].memory_8bit_i.mem[i] = mseq8r;
mseq8r = mseqf8_R(mseq8r);
end
end
initial begin : memory_init_green
integer i;
for (i=0; i<480000; i=i+1) begin
uut.system_i.mem_sim_axi_slave_0.mem_sim_axi_slave_0.MEMORY_GEN[1].memory_8bit_i.mem[i] = mseq8g;
mseq8g = mseqf8_G(mseq8g);
end
end
initial begin : memory_init_blue
integer i;
for (i=0; i<480000; i=i+1) begin
uut.system_i.mem_sim_axi_slave_0.mem_sim_axi_slave_0.MEMORY_GEN[0].memory_8bit_i.mem[i] = mseq8b;
mseq8b = mseqf8_B(mseq8b);
end
end
`default_nettype none
module calculation_test(
input wire [7:0] a,
input wire [7:0] b,
input wire signed [7:0] sc,
input wire signed [7:0] sd,
input wire [7:0] e,
input wire signed [7:0] sf,
output wire [7:0] x1,
output wire [8:0] x2,
output wire signed [8:0] sy1,
output wire signed [8:0] sy2,
output wire signed [8:0] sz1,
output wire signed [8:0] sz2
);
// unsigned - unsigned
assign x1 = a - b;
assign x2 = {1'b0, a} - {1'b0, b}; // ビット幅を合わせた
// signed - signed
assign sy1 = sc - sd;
assign sy2 = {sc[7], sc} - {sd[7], sd}; // 明示的に符号拡張
// signed - $signed(unsigned)
assign sz1 = sf - $signed(e);
assign sz2 = sf - $signed({1'b0, e[6:0]});
endmodule
`timescale 1ns / 1ps
module calculation_test_tb;
parameter DELAY = 10;
// Inputs
reg [7:0] a;
reg [7:0] b;
reg signed [7:0] sc;
reg signed [7:0] sd;
reg [7:0] e;
reg signed [7:0] sf;
// Outputs
wire [7:0] x1;
wire [8:0] x2;
wire signed [8:0] sy1;
wire signed [8:0] sy2;
wire signed [8:0] sz1;
wire signed [8:0] sz2;
// Instantiate the Unit Under Test (UUT)
calculation_test uut (
.a(a),
.b(b),
.sc(sc),
.sd(sd),
.e(e),
.sf(sf),
.x1(x1),
.x2(x2),
.sy1(sy1),
.sy2(sy2),
.sz1(sz1),
.sz2(sz2)
);
initial begin
// Initialize Inputs
a = 0;
b = 0;
sc = 0;
sd = 0;
e = 0;
sf = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
a = 3; b = 2;
#DELAY;
$display("x = a - b");
if (x1>=0)
$display("a=%d, b=%d, x1=%d, x1>=0", a, b,x1);
else
$display("a=%d, b=%d, x1=%d, x1<0", a, b,x1);
if (x2>=0)
$display("a=%d, b=%d, x2=%d, x2>=0", a, b,x1);
else
$display("a=%d, b=%d, x2=%d, x2<0", a, b,x1);
sc = 3; sd = 2;
#DELAY;
$display("sy = sc - sd");
if (sy1>=0)
$display("sc=%d, sd=%d, sy1=%d, sy1>=0", sc, sd, sy1);
else
$display("sc=%d, sd=%d, sy1=%d, sy1<0", sc, sd, sy1);
if (sy2>=0)
$display("sc=%d, sd=%d, sy2=%d, sy2>=0", sc, sd, sy2);
else
$display("sc=%d, sd=%d, sy2=%d, sy2<0", sc, sd, sy2);
sf = 3; e = 2;
#DELAY;
$display("sz = sf - e");
if (sz1>=0)
$display("sf=%d, e=%d, sz1=%d, sz1>=0", sf, e, sz1);
else
$display("sf=%d, e=%d, sz1=%d, sz1<0", sf, e, sz1);
if (sz2>=0)
$display("sf=%d, e=%d, sz2=%d, sz2>=0", sf, e, sz2);
else
$display("sf=%d, e=%d, sz2=%d, sz2<0", sf, e, sz2);
$display("");
a = 2; b = 3;
#DELAY;
$display("x = a - b");
if (x1>=0)
$display("a=%d, b=%d, x1=%d, x1>=0", a, b,x1);
else
$display("a=%d, b=%d, x1=%d, x1<0", a, b,x1);
if (x2>=0)
$display("a=%d, b=%d, x2=%d, x2>=0", a, b,x1);
else
$display("a=%d, b=%d, x2=%d, x2<0", a, b,x1);
sc = 2; sd = 3;
#DELAY;
$display("sy = sc - sd");
if (sy1>=0)
$display("sc=%d, sd=%d, sy1=%d, sy1>=0", sc, sd, sy1);
else
$display("sc=%d, sd=%d, sy1=%d, sy1<0", sc, sd, sy1);
if (sy2>=0)
$display("sc=%d, sd=%d, sy2=%d, sy2>=0", sc, sd, sy2);
else
$display("sc=%d, sd=%d, sy2=%d, sy2<0", sc, sd, sy2);
sf = 2; e = 3;
#DELAY;
$display("sz = sf - e");
if (sz1>=0)
$display("sf=%d, e=%d, sz1=%d, sz1>=0", sf, e, sz1);
else
$display("sf=%d, e=%d, sz1=%d, sz1<0", sf, e, sz1);
if (sz2>=0)
$display("sf=%d, e=%d, sz2=%d, sz2>=0", sf, e, sz2);
else
$display("sf=%d, e=%d, sz2=%d, sz2<0", sf, e, sz2);
$display("");
a = -128; b = 128;
#DELAY;
$display("x = a - b");
if (x1>=0)
$display("a=%d, b=%d, x1=%d, x1>=0", a, b,x1);
else
$display("a=%d, b=%d, x1=%d, x1<0", a, b,x1);
if (x2>=0)
$display("a=%d, b=%d, x2=%d, x2>=0", a, b,x1);
else
$display("a=%d, b=%d, x2=%d, x2<0", a, b,x1);
sc = -128; sd = 128;
#DELAY;
$display("sy = sc - sd");
if (sy1>=0)
$display("sc=%d, sd=%d, sy1=%d, sy1>=0", sc, sd, sy1);
else
$display("sc=%d, sd=%d, sy1=%d, sy1<0", sc, sd, sy1);
if (sy2>=0)
$display("sc=%d, sd=%d, sy2=%d, sy2>=0", sc, sd, sy2);
else
$display("sc=%d, sd=%d, sy2=%d, sy2<0", sc, sd, sy2);
sf = -128; e = 127;
#DELAY;
$display("sz = sf - e");
if (sz1>=0)
$display("sf=%d, e=%d, sz1=%d, sz1>=0", sf, e, sz1);
else
$display("sf=%d, e=%d, sz1=%d, sz1<0", sf, e, sz1);
if (sz2>=0)
$display("sf=%d, e=%d, sz2=%d, sz2>=0", sf, e, sz2);
else
$display("sf=%d, e=%d, sz2=%d, sz2<0", sf, e, sz2);
end
endmodule
x = a - b
a= 3, b= 2, x1= 1, x1>=0
a= 3, b= 2, x2= 1, x2>=0
sy = sc - sd
sc= 3, sd= 2, sy1= 1, sy1>=0
sc= 3, sd= 2, sy2= 1, sy2>=0
sz = sf - e
sf= 3, e= 2, sz1= 1, sz1>=0
sf= 3, e= 2, sz2= 1, sz2>=0
x = a - b
a= 2, b= 3, x1=255, x1>=0
a= 2, b= 3, x2=255, x2>=0
sy = sc - sd
sc= 2, sd= 3, sy1= -1, sy1<0
sc= 2, sd= 3, sy2= -1, sy2<0
sz = sf - e
sf= 2, e= 3, sz1= -1, sz1<0
sf= 2, e= 3, sz2= -1, sz2<0
x = a - b
a=128, b=128, x1= 0, x1>=0
a=128, b=128, x2= 0, x2>=0
sy = sc - sd
sc=-128, sd=-128, sy1= 0, sy1>=0
sc=-128, sd=-128, sy2= 0, sy2>=0
sz = sf - e
sf=-128, e=127, sz1=-255, sz1<0
sf=-128, e=127, sz2=-255, sz2<0
wire [31:0] data;
wire signed [31:0] data;
assign data3 = $signed({1'b0, data1}) - $signed({1'b0, data2});
// 8bit Memory Module
`default_nettype none
module memory_8bit #(
parameter integer C_S_AXI_ADDR_WIDTH = 32,
parameter integer C_MEMORY_SIZE = 512 // Word (not byte)
)(
input wire clk,
input wire [C_S_AXI_ADDR_WIDTH-1:0] waddr,
input wire [7:0] write_data,
input wire write_enable,
input wire byte_enable,
input wire [C_S_AXI_ADDR_WIDTH-1:0] raddr,
output reg [7:0] read_data
);
// Beyond Circuts, Constant Function in Verilog 2001を参照しました
// http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/
function integer log2;
input integer addr;
begin
addr = addr - 1;
for (log2=0; addr>0; log2=log2+1)
addr = addr >> 1;
end
endfunction
reg [7:0] mem [0:C_MEMORY_SIZE-1];
wire [log2(C_MEMORY_SIZE)-1:0] mem_waddr;
wire [log2(C_MEMORY_SIZE)-1:0] mem_raddr;
// The Address is byte address
assign mem_waddr = waddr[(log2(C_MEMORY_SIZE)+log2((C_S_AXI_ADDR_WIDTH/8)))-1:log2((C_S_AXI_ADDR_WIDTH/8))];
assign mem_raddr = raddr[(log2(C_MEMORY_SIZE)+log2((C_S_AXI_ADDR_WIDTH/8)))-1:log2((C_S_AXI_ADDR_WIDTH/8))];
// Write
always @(posedge clk) begin
if (write_enable & byte_enable)
mem[mem_waddr] <= write_data;
end
// Read
always @(posedge clk) begin
read_data <= mem[mem_raddr];
end
endmodule
`default_nettype wire
//
// Initializing Block RAM from external data file
//
module v_rams_20c (clk, we, addr, din, dout);
input clk;
input we;
input [4:0] addr;
input [15:0] din;
output [15:0] dout;
reg [15:0] ram [0:31];
reg [15:0] dout;
initial begin
$readmemh("rams_20c.data",ram, 0, 31);
end
always @(posedge clk) begin
if (we)
ram[addr] <= din;
dout <= ram[addr];
end
endmodule
AABB
CCDD
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
reg [15:0] ram [0:31];
(* RAM_STYLE="BLOCK" *) reg [15:0] ram [0:31];
//
// Initializing Block RAM from external data file
//
module v_rams_20c (clk, we, addr, din, dout);
input clk;
input [1:0] we;
input [4:0] addr;
input [15:0] din;
output [15:0] dout;
(* RAM_STYLE="BLOCK" *) reg [15:0] ram [0:31];
// reg [15:0] ram [0:31];
reg [15:0] dout;
initial begin
$readmemh("rams_20c.data",ram, 0, 31);
end
always @(posedge clk) begin
dout <= ram[addr];
if (we[0])
ram[addr][7:0] <= din[7:0];
if (we[1])
ram[addr][15:8] <= din[15:8];
end
endmodule
//
// Initializing Block RAM from external data file
//
module v_rams_20c (clk, we, addr, din, dout);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 5;
input wire [DATA_WIDTH-1:0] din;
input wire [ADDR_WIDTH-1:0] addr;
input wire [1:0] we;
input wire clk;
output reg [DATA_WIDTH-1:0] dout;
wire ram_ena;
assign ram_ena = 1'b1;
(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
reg [(DATA_WIDTH/2)-1:0] di0, di1;
// The following code is only necessary if you wish to initialize the RAM
// contents via an external file (use $readmemb for binary data)
initial
$readmemh("rams_20c.data", ram, 0, 31);
always @(we, din) begin
if (we[0])
di0 = din[(DATA_WIDTH/2)-1:0];
else
di0 = ram[addr][(DATA_WIDTH/2)-1:0];
if (we[1])
di1 = din[DATA_WIDTH-1:DATA_WIDTH/2];
else
di1 = ram[addr][DATA_WIDTH-1:DATA_WIDTH/2];
end
always @(posedge clk)
if (ram_ena) begin
dout <= {di1,di0};
ram[addr] <= {di1,di0};
end
endmodule
Spartan-3 SLICEM
Spartan-3E SLICEM
Spartan-3A Block RAM
Virtex-4 Block RAM
Virtex-5 Block RAM
Spartan-6 Block RAM
Virtex-6 Block RAM
module add #(parameter width = 8)
add #(.width(4) ) add_u(.clk(clk), .a(a), .b(b), .c(c));
module ddr2_sdram_cont (clk_in, clk_out, reset, input_data, input_mask...);
`include "./ddr2_cont_parameters.vh"
input clk_in; // クロック入力
output clk_out; // クロック出力
input reset;
input [INTERFACE_DATA_WIDTH-1 : 0] input_data;
input [INTERFACE_MASK_WIDTH-1 : 0] input_mask;
parameter DDR2_DATA_WIDTH = 16; // DDR2 SDRAMのデータ幅
parameter INTERFACE_DATA_WIDTH = DDR2_DATA_WIDTH*2; // DDR2 SDRAMは4バースト、2倍データ幅で2回書き込む
parameter INTERFACE_MASK_WIDTH = INTERFACE_DATA_WIDTH/8; // BEの幅
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | - | 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 |