video sprite example working! kinda frankensteined tho

This commit is contained in:
Fischer Moseley 2023-04-13 17:02:55 -04:00
parent 161f949c36
commit 153ae7e3df
21 changed files with 359 additions and 66108 deletions

View File

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,256 +0,0 @@
fed
fec
eed
fdd
fdc
edd
edc
edb
ddc
ddb
ecc
ecb
dcc
dcb
dca
ccb
cca
dbb
dba
cbb
cba
cb9
cb8
caa
ca9
ca8
ba9
ba8
c99
c98
b99
b98
b97
b88
b87
a98
a97
a96
a88
a87
a86
987
986
a76
977
976
975
966
965
876
875
866
865
864
765
764
855
854
853
755
754
753
844
843
744
743
654
653
644
643
642
543
542
733
732
633
632
722
622
533
532
522
521
432
431
422
421
321
511
411
311
310
210
300
200
100
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000

View File

@ -2,13 +2,8 @@
cores:
image_mem:
type: block_memory
width: 8
depth: 65536
pallete_mem:
type: block_memory
width: 10
depth: 256
width: 12
depth: 16384
uart:
port: "auto"

View File

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,37 @@
import sys
from PIL import Image, ImageOps
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {0} <image to convert>".format(sys.argv[0]))
else:
input_fname = sys.argv[1]
image_in = Image.open(input_fname)
image_in = image_in.convert('RGB')
# Resize the image
image_in = image_in.resize((128, 128))
image_out = image_in.copy()
w, h = image_in.size
# Take input image and divide each color channel's value by 16
for y in range(h):
for x in range(w):
r, g, b = image_in.getpixel((x, y))
image_out.putpixel((x,y), (r//16, g//16, b//16))
# Save the image itself
pixels = []
for y in range(h):
for x in range(w):
(r, g, b) = image_out.getpixel((x,y))
color = (r*16*16) + (g*16) + (b)
pixels.append(color)
from manta import Manta
m = Manta('manta.yaml')
for addr, pixel in enumerate(pixels):
m.image_mem.write(addr, pixel)

View File

@ -1,51 +0,0 @@
`timescale 1ns / 1ps
`default_nettype none
module alpha_tester(input wire [2:0] alpha_in,
input wire [11:0] a_in,
input wire [11:0] b_in,
output logic [11:0] pixel_out);
// your (combinational) alpha blending logic goes here!
// replace the code below with your bit math
logic [3:0] r, g, b;
assign r = 0;
assign g = 0;
assign b = 0;
assign pixel_out = {r, g, b};
endmodule
module alpha_tb;
logic [2:0] alpha_in;
logic [11:0] a_in;
logic [11:0] b_in;
logic [11:0] pixel_out;
alpha_tester uut (.alpha_in(alpha_in),
.a_in(a_in),
.b_in(b_in),
.pixel_out(pixel_out));
//initial block...this is our test simulation
initial begin
$dumpfile("alpha.vcd"); //file to store value change dump (vcd)
$dumpvars(0,alpha_tb); //store everything at the current level and below
$display("Starting Sim"); //print nice message
a_in = 12'hF00;
b_in = 12'hFFF;
alpha_in = 0;
#10 //wait a little bit of time at beginning
$display("a_in = %12b b_in = %12b",a_in, b_in);
for (integer i = 0; i<5; i= i+1)begin
alpha_in = i;
#10;
$display("alpha_in = %d pixel_out = %03h", alpha_in, pixel_out);
end
#100;
$display("Finishing Sim"); //print nice message
$finish;
end
endmodule //counter_tb
`default_nettype wire

View File

@ -1,50 +0,0 @@
`timescale 1ns / 1ps
`default_nettype none
module image_sprite_tb;
//make logics for inputs and outputs!
logic pixel_clk_in;
logic rst_in;
logic [11:0] pixel_out;
logic [10:0] hcount_in;
image_sprite #(.WIDTH(256), .HEIGHT(256))
uut
( .pixel_clk_in(pixel_clk_in),
.rst_in(rst_in),
.x_in(11'd256),
.hcount_in(hcount_in),
.y_in(10'd256),
.vcount_in(10'd380),
.pixel_out(pixel_out)
);
always begin
#5; //every 5 ns switch...so period of clock is 10 ns...100 MHz clock
pixel_clk_in = !pixel_clk_in;
end
//initial block...this is our test simulation
initial begin
$dumpfile("image_sprite.vcd"); //file to store value change dump (vcd)
$dumpvars(0,image_sprite_tb); //store everything at the current level and below
$display("Starting Sim"); //print nice message
pixel_clk_in = 0; //initialize clk (super important)
rst_in = 0; //initialize rst (super important)
hcount_in = 0;
#10 //wait a little bit of time at beginning
rst_in = 1; //reset system
#10; //hold high for a few clock cycles
rst_in=0;
#10;
for (hcount_in = 0; hcount_in<1025; hcount_in = hcount_in + 1)begin
#10;
end
#100;
$display("Finishing Sim"); //print nice message
$finish;
end
endmodule //counter_tb
`default_nettype wire

View File

@ -0,0 +1,60 @@
// Xilinx True Dual Port RAM, Read First, Dual Clock
// This code implements a parameterizable true dual port memory (both ports can read and write).
// The behavior of this RAM is when data is written, the prior memory contents at the write
// address are presented on the output port. If the output data is
// not needed during writes or the last read value is desired to be retained,
// it is suggested to use a no change RAM as it is more power efficient.
// If a reset or enable is not necessary, it may be tied off or removed from the code.
// Modified from the xilinx_true_dual_port_read_first_2_clock_ram verilog language template.
module dual_port_bram #(
parameter RAM_WIDTH = 0,
parameter RAM_DEPTH = 0
) (
input wire [$clog2(RAM_DEPTH-1)-1:0] addra,
input wire [$clog2(RAM_DEPTH-1)-1:0] addrb,
input wire [RAM_WIDTH-1:0] dina,
input wire [RAM_WIDTH-1:0] dinb,
input wire clka,
input wire clkb,
input wire wea,
input wire web,
output wire [RAM_WIDTH-1:0] douta,
output wire [RAM_WIDTH-1:0] doutb
);
// The following code either initializes the memory values to a specified file or to all zeros to match hardware
generate
integer i;
initial begin
for (i = 0; i < RAM_DEPTH; i = i + 1)
BRAM[i] = {RAM_WIDTH{1'b0}};
end
endgenerate
reg [RAM_WIDTH-1:0] BRAM [RAM_DEPTH-1:0];
reg [RAM_WIDTH-1:0] ram_data_a = {RAM_WIDTH{1'b0}};
reg [RAM_WIDTH-1:0] ram_data_b = {RAM_WIDTH{1'b0}};
always @(posedge clka) begin
if (wea) BRAM[addra] <= dina;
ram_data_a <= BRAM[addra];
end
always @(posedge clkb) begin
if (web) BRAM[addrb] <= dinb;
ram_data_b <= BRAM[addrb];
end
// Add a 2 clock cycle read latency to improve clock-to-out timing
reg [RAM_WIDTH-1:0] douta_reg = {RAM_WIDTH{1'b0}};
reg [RAM_WIDTH-1:0] doutb_reg = {RAM_WIDTH{1'b0}};
always @(posedge clka) douta_reg <= ram_data_a;
always @(posedge clkb) doutb_reg <= ram_data_b;
assign douta = douta_reg;
assign doutb = doutb_reg;
endmodule

View File

@ -1,5 +0,0 @@
`ifdef SYNTHESIS
`define FPATH(X) `"X`"
`else /* ! SYNTHESIS */
`define FPATH(X) `"data/X`"
`endif /* ! SYNTHESIS */

View File

@ -0,0 +1,85 @@
module ssd(
input wire clk_in,
input wire rst_in,
input wire [31:0] val_in,
output reg[6:0] cat_out,
output reg[7:0] an_out);
parameter COUNT_TO = 100000;
logic[7:0] segment_state;
logic[31:0] segment_counter;
logic [3:0] routed_vals;
logic [6:0] led_out;
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
assign cat_out = ~led_out;
assign an_out = ~segment_state;
always @(*) begin
case(segment_state)
8'b0000_0001: routed_vals = val_in[3:0];
8'b0000_0010: routed_vals = val_in[7:4];
8'b0000_0100: routed_vals = val_in[11:8];
8'b0000_1000: routed_vals = val_in[15:12];
8'b0001_0000: routed_vals = val_in[19:16];
8'b0010_0000: routed_vals = val_in[23:20];
8'b0100_0000: routed_vals = val_in[27:24];
8'b1000_0000: routed_vals = val_in[31:28];
default: routed_vals = val_in[3:0];
endcase
end
always @(posedge clk_in) begin
if (rst_in) begin
segment_state <= 8'b0000_0001;
segment_counter <= 32'b0;
end
else begin
if (segment_counter == COUNT_TO) begin
segment_counter <= 32'd0;
segment_state <= {segment_state[6:0],segment_state[7]};
end else begin
segment_counter <= segment_counter +1;
end
end
end
endmodule
module bto7s(
input wire [3:0] x_in,
output reg [6:0] s_out);
reg sa, sb, sc, sd, se, sf, sg;
assign s_out = {sg, sf, se, sd, sc, sb, sa};
// array of bits that are "one hot" with numbers 0 through 15
reg [15:0] num;
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
assign num[2] = x_in == 4'd2;
assign num[3] = x_in == 4'd3;
assign num[4] = x_in == 4'd4;
assign num[5] = x_in == 4'd5;
assign num[6] = x_in == 4'd6;
assign num[7] = x_in == 4'd7;
assign num[8] = x_in == 4'd8;
assign num[9] = x_in == 4'd9;
assign num[10] = x_in == 4'd10;
assign num[11] = x_in == 4'd11;
assign num[12] = x_in == 4'd12;
assign num[13] = x_in == 4'd13;
assign num[14] = x_in == 4'd14;
assign num[15] = x_in == 4'd15;
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
endmodule

View File

@ -1,91 +1,89 @@
`timescale 1ns / 1ps
`default_nettype none
`timescale 1ns / 1ps
`default_nettype none
module top_level(
input wire clk_100mhz,
input wire [15:0] sw,
input wire btnc, btnu, btnl, btnr, btnd,
module top_level(
input wire clk_100mhz,
output logic [15:0] led,
output logic [3:0] vga_r, vga_g, vga_b,
output logic vga_hs, vga_vs,
output logic [3:0] vga_r, vga_g, vga_b,
output logic vga_hs, vga_vs
);
input wire btnc,
output logic [15:0] led,
output logic ca, cb, cc, cd, ce, cf, cg,
output logic [7:0] an,
logic clk_65mhz;
input wire uart_txd_in,
output logic uart_rxd_out);
clk_wiz_lab3 clk_gen(
.clk_in1(clk_100mhz),
.clk_out1(clk_65mhz));
logic clk_65mhz;
// VGA signals
logic [10:0] hcount;
logic [9:0] vcount;
logic hsync, vsync, blank;
clk_wiz_lab3 clk_gen(
.clk_in1(clk_100mhz),
.clk_out1(clk_65mhz));
vga vga_gen(
.pixel_clk_in(clk_65mhz),
.hcount_out(hcount),
.vcount_out(vcount),
.hsync_out(hsync),
.vsync_out(vsync),
.blank_out(blank));
// VGA signals
logic [10:0] hcount;
logic [9:0] vcount;
logic hsync, vsync, blank;
localparam WIDTH = 256;
localparam HEIGHT = 256;
vga vga_gen(
.pixel_clk_in(clk_65mhz),
.hcount_out(hcount),
.vcount_out(vcount),
.hsync_out(hsync),
.vsync_out(vsync),
.blank_out(blank));
// calculate rom address
logic [$clog2(WIDTH*HEIGHT)-1:0] image_addr;
assign image_addr = (hcount_in - x_in) + ((vcount_in - y_in) * WIDTH);
localparam WIDTH = 128;
localparam HEIGHT = 128;
logic in_sprite;
assign in_sprite = ((hcount_in >= x_in && hcount_in < (x_in + WIDTH)) &&
(vcount_in >= y_in && vcount_in < (y_in + HEIGHT)));
localparam X = 0;
localparam Y = 0;
// image BRAM
xilinx_single_port_ram_read_first #(
.RAM_WIDTH(8),
.RAM_DEPTH(WIDTH*HEIGHT),
.RAM_PERFORMANCE("HIGH_PERFORMANCE"),
.INIT_FILE(`FPATH(image.mem))
) image_bram (
.addra(image_addr),
.dina(),
.clka(clk_65mhz),
.wea(1'b0),
.ena(1'b1),
.rsta(1'b0),
.regcea(1'b1),
.douta(color_lookup));
// calculate rom address
logic [$clog2(WIDTH*HEIGHT)-1:0] image_addr;
assign image_addr = (hcount - X) + ((vcount - Y) * WIDTH);
// lookup
logic [7:0] color_lookup;
logic in_sprite;
assign in_sprite = ((hcount >= X && hcount < (X + WIDTH)) &&
(vcount >= Y && vcount < (Y + HEIGHT)));
// pallete BRAM
xilinx_single_port_ram_read_first #(
.RAM_WIDTH(12),
.RAM_DEPTH(256),
.RAM_PERFORMANCE("HIGH_PERFORMANCE"),
.INIT_FILE(`FPATH(palette.mem))
) pallete_bram (
.addra(color_lookup),
.dina(),
.clka(clk_65mhz),
.wea(1'b0),
.ena(1'b1),
.rsta(1'b0),
.regcea(1'b1),
.douta(color));
manta manta_inst (
.clk(clk_65mhz),
logic [11:0] color;
.rx(uart_txd_in),
.tx(uart_rxd_out),
// the following lines are required for the Nexys4 VGA circuit - do not change
assign vga_r = ~blank ? color[11:8]: 0;
assign vga_g = ~blank ? color[7:4] : 0;
assign vga_b = ~blank ? color[3:0] : 0;
.image_mem_clk(clk_65mhz),
.image_mem_addr(image_addr),
.image_mem_din(),
.image_mem_dout(sprite_color),
.image_mem_we(1'b0));
assign vga_hs = ~hsync;
assign vga_vs = ~vsync;
endmodule
logic [11:0] sprite_color;
logic [11:0] color;
assign color = in_sprite ? sprite_color : 12'h0;
`default_nettype wire
// the following lines are required for the Nexys4 VGA circuit - do not change
assign vga_r = ~blank ? color[11:8]: 0;
assign vga_g = ~blank ? color[7:4] : 0;
assign vga_b = ~blank ? color[3:0] : 0;
assign vga_hs = ~hsync;
assign vga_vs = ~vsync;
// debug
assign led = manta_inst.brx_image_mem_addr;
logic [6:0] cat;
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
ssd ssd (
.clk_in(clk_65mhz),
.rst_in(btnc),
.val_in( {manta_inst.image_mem_btx_rdata, manta_inst.brx_image_mem_wdata} ),
.cat_out(cat),
.an_out(an));
endmodule
`default_nettype wire

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,48 +0,0 @@
import sys
from PIL import Image, ImageOps
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {0} <image to convert>".format(sys.argv[0]))
else:
input_fname = sys.argv[1]
image_in = Image.open(input_fname)
image_in = image_in.convert('RGB')
num_colors_out = 256
w, h = image_in.size
print(f'Reducing {input_fname} of size {w}x{h} to {num_colors_out} unique colors.')
# Take input image and divide each color channel's value by 16
preview = image_in.copy()
image_out = image_in.copy()
for y in range(h):
for x in range(w):
r, g, b = image_in.getpixel((x, y))
image_out.putpixel((x,y), (r//16, g//16, b//16))
preview.putpixel((x,y), ((r//16)*16, (g//16)*16, (b//16)*16) )
# Save the image preview
preview.save('preview.png')
print('Output image preview saved at preview.png')
# Palettize the image
image_out = image_out.convert(mode='P', palette=1, colors=num_colors_out)
palette = image_out.getpalette()
rgb_tuples = [tuple(palette[i:i+3]) for i in range(0, 3*num_colors_out, 3)]
# Save pallete
with open(f'palette.mem', 'w') as f:
f.write( '\n'.join( [f'{r:01x}{g:01x}{b:01x}' for r, g, b in rgb_tuples] ) )
print('Output image pallete saved at palette.mem')
# Save the image itself
with open(f'image.mem', 'w') as f:
for y in range(h):
for x in range(w):
f.write(f'{image_out.getpixel((x,y)):02x}\n')
print('Output image saved at image.mem')

View File

@ -18,22 +18,22 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {cl
##Switches
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
# set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
# set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
# set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
# set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
# set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
# set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
# set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
# set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
# set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
# set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
# set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
# set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
# set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
# set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
# set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
# set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
@ -65,35 +65,35 @@ set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15
##7 segment display
# set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
# set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
# set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
# set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
# set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
# set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
# set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
# set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
# set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
# set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
# set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
# set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
# set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
# set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
# set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
# set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
# set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
# set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
# set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
# set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
@ -223,8 +223,8 @@ set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs
##USB-RS232 Interface
#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts

View File

@ -677,15 +677,13 @@ class BlockMemoryCore:
def hdl_inst(self):
inst = VerilogManipulator("block_memory_inst_tmpl.v")
# inst.sub(self.name, "/* INST_NAME */")
# inst.sub(self.depth, "/* DEPTH */")
# inst.sub(self.width, "/* WIDTH */")
inst.sub(self.name, "/* INST_NAME */")
inst.sub(self.depth, "/* DEPTH */")
inst.sub(self.width, "/* WIDTH */")
return inst.get_hdl()
def hdl_def(self):
bram_core = VerilogManipulator("block_memory_tmpl.v")
bram_core.sub(self.name, "/* NAME */")
return bram_core.get_hdl()
return VerilogManipulator("block_memory_tmpl.v").get_hdl()
def hdl_top_level_ports(self):
@ -693,11 +691,11 @@ class BlockMemoryCore:
return ""
tlp = []
tlp.append(f"input wire {self.name}_clk,")
tlp.append(f"input wire {self.name}_clk")
tlp.append(f"input wire [{self.addr_width-1}:0] {self.name}_addr")
tlp.append(f"input wire [{self.addr_width-1}:0] {self.name}_din")
tlp.append(f"input wire [{self.addr_width-1}:0] {self.name}_dout")
tlp.append(f"input wire [{self.addr_width-1}:0] {self.name}_we")
tlp.append(f"input wire [{self.width-1}:0] {self.name}_din")
tlp.append(f"output reg [{self.width-1}:0] {self.name}_dout")
tlp.append(f"input wire {self.name}_we")
return tlp
def read(self, addr):
@ -786,11 +784,11 @@ class Manta:
src = core_pair[0].name
dst = core_pair[1].name
hdl = f"\treg [15:0] {src}_{dst}_addr;\n"
hdl += f"\treg [15:0] {src}_{dst}_wdata;\n"
hdl += f"\treg [15:0] {src}_{dst}_rdata;\n"
hdl += f"\treg {src}_{dst}_rw;\n"
hdl += f"\treg {src}_{dst}_valid;\n"
hdl = f"reg [15:0] {src}_{dst}_addr;\n"
hdl += f"reg [15:0] {src}_{dst}_wdata;\n"
hdl += f"reg [15:0] {src}_{dst}_rdata;\n"
hdl += f"reg {src}_{dst}_rw;\n"
hdl += f"reg {src}_{dst}_valid;\n"
conns.append(hdl)
return conns
@ -821,7 +819,7 @@ class Manta:
# connect output
if (i < len(self.cores)-1):
dst_name = self.cores[i+1]
dst_name = self.cores[i+1].name
hdl = hdl.replace(".addr_o()", f".addr_o({core.name}_{dst_name}_addr)")
hdl = hdl.replace(".wdata_o()", f".wdata_o({core.name}_{dst_name}_wdata)")
@ -920,10 +918,10 @@ class Manta:
# connect interface_rx to core_chain
interface_rx_conn= f"""
reg [15:0] brx_{self.cores[0].name}_addr;
reg [15:0] brx_{self.cores[0].name}_wdata;
reg brx_{self.cores[0].name}_rw;
reg brx_{self.cores[0].name}_valid;\n"""
reg [15:0] brx_{self.cores[0].name}_addr;
reg [15:0] brx_{self.cores[0].name}_wdata;
reg brx_{self.cores[0].name}_rw;
reg brx_{self.cores[0].name}_valid;\n"""
return interface_rx_inst + interface_rx_conn
@ -931,9 +929,9 @@ class Manta:
# connect core_chain to interface_tx
interface_tx_conn = f"""
reg [15:0] {self.cores[-1].name}_btx_rdata;
reg {self.cores[-1].name}_btx_rw;
reg {self.cores[-1].name}_btx_valid;\n"""
reg [15:0] {self.cores[-1].name}_btx_rdata;
reg {self.cores[-1].name}_btx_rw;
reg {self.cores[-1].name}_btx_valid;\n"""
# instantiate interface_tx, substitute in register names
interface_tx_inst = self.interface.tx_hdl_inst()

View File

@ -0,0 +1,23 @@
block_memory #(
.WIDTH(/* WIDTH */),
.DEPTH(/* DEPTH */)
) /* INST_NAME */ (
.clk(clk),
.addr_i(),
.wdata_i(),
.rdata_i(),
.rw_i(),
.valid_i(),
.user_clk(/* INST_NAME */_clk),
.user_addr(/* INST_NAME */_addr),
.user_din(/* INST_NAME */_din),
.user_dout(/* INST_NAME */_dout),
.user_we(/* INST_NAME */_we),
.addr_o(),
.wdata_o(),
.rdata_o(),
.rw_o(),
.valid_o());

View File

@ -1,7 +1,7 @@
`default_nettype none
`timescale 1ns/1ps
module /* NAME */ (
module block_memory (
input wire clk,
// input port
@ -21,18 +21,18 @@ module /* NAME */ (
// BRAM itself
input wire user_clk,
input wire [ADDR_WIDTH-1:0] user_addr,
input wire [BRAM_WIDTH-1:0] user_din,
output reg [BRAM_WIDTH-1:0] user_dout,
input wire [WIDTH-1:0] user_din,
output reg [WIDTH-1:0] user_dout,
input wire user_we);
parameter BASE_ADDR = 0;
parameter BRAM_WIDTH = 0;
parameter BRAM_DEPTH = 0;
localparam ADDR_WIDTH = $clog2(BRAM_DEPTH);
parameter WIDTH = 0;
parameter DEPTH = 0;
localparam ADDR_WIDTH = $clog2(DEPTH);
// ugly typecasting, but just computes ceil(BRAM_WIDTH / 16)
localparam N_BRAMS = int'($ceil(real'(BRAM_WIDTH) / 16.0));
localparam MAX_ADDR = BASE_ADDR + (BRAM_DEPTH * N_BRAMS);
// ugly typecasting, but just computes ceil(WIDTH / 16)
localparam N_BRAMS = int'($ceil(real'(WIDTH) / 16.0));
localparam MAX_ADDR = BASE_ADDR + (DEPTH * N_BRAMS);
// Port A of BRAMs
reg [N_BRAMS-1:0][ADDR_WIDTH-1:0] addra = 0;
@ -48,14 +48,14 @@ module /* NAME */ (
// kind of a hack to part select from a 2d array that's been flattened to 1d
reg [(N_BRAMS*16)-1:0] doutb_flattened;
assign doutb_flattened = doutb;
assign user_dout = doutb_flattened[BRAM_WIDTH-1:0];
assign user_dout = doutb_flattened[WIDTH-1:0];
// Pipelining
reg [3:0][15:0] addr_pipe = 0;
reg [3:0][15:0] wdata_pipe = 0;
reg [3:0][15:0] rdata_pipe = 0;
reg [3:0] valid_pipe = 0;
reg [3:0] rw_pipe = 0;
reg [2:0][15:0] addr_pipe = 0;
reg [2:0][15:0] wdata_pipe = 0;
reg [2:0][15:0] rdata_pipe = 0;
reg [2:0] valid_pipe = 0;
reg [2:0] rw_pipe = 0;
always @(posedge clk) begin
addr_pipe[0] <= addr_i;
@ -70,7 +70,7 @@ module /* NAME */ (
valid_o <= valid_pipe[2];
rw_o <= rw_pipe[2];
for(int i=1; i<4; i=i+1) begin
for(int i=1; i<3; i=i+1) begin
addr_pipe[i] <= addr_pipe[i-1];
wdata_pipe[i] <= wdata_pipe[i-1];
rdata_pipe[i] <= rdata_pipe[i-1];
@ -98,7 +98,7 @@ module /* NAME */ (
for(i=0; i<N_BRAMS; i=i+1) begin
dual_port_bram #(
.RAM_WIDTH(16),
.RAM_DEPTH(BRAM_DEPTH)
.RAM_DEPTH(DEPTH)
) bram_full_width_i (
// port A is controlled by the bus

View File

@ -1,4 +1,4 @@
module my_bram (
module block_memory (
input wire clk,
// input port
@ -27,8 +27,9 @@ module my_bram (
parameter BRAM_DEPTH = 0;
localparam ADDR_WIDTH = $clog2(BRAM_DEPTH);
localparam MAX_ADDR = BASE_ADDR + (BRAM_DEPTH * N_BRAMS);
// ugly typecasting, but just computes ceil(BRAM_WIDTH / 16)
localparam N_BRAMS = int'($ceil(real'(BRAM_WIDTH) / 16.0));
localparam MAX_ADDR = BASE_ADDR + (BRAM_DEPTH * N_BRAMS);
// Port A of BRAMs
reg [N_BRAMS-1:0][ADDR_WIDTH-1:0] addra = 0;

View File

@ -82,7 +82,7 @@ module block_memory_tb;
logic [BRAM_WIDTH-1:0] bram_user_dout;
logic bram_user_we = 0;
my_bram #(.BRAM_DEPTH(BRAM_DEPTH), .BRAM_WIDTH(BRAM_WIDTH)) my_bram_inst(
block_memory #(.BRAM_DEPTH(BRAM_DEPTH), .BRAM_WIDTH(BRAM_WIDTH)) my_bram_inst(
.clk(clk),
.addr_i(tb_bc_addr),