first commit

This commit is contained in:
2025-11-24 21:44:39 -05:00
commit 1b017953ee
22 changed files with 240604 additions and 0 deletions

84
rtl/Basys3_Top.v Normal file
View File

@@ -0,0 +1,84 @@
module Basys3_Top (
input clk,
output [15:0] led,
output [6:0] seg,
output [3:0] an,
output dp,
output Hsync,
output Vsync,
output [3:0] vgaRed,
output [3:0] vgaGreen,
output [3:0] vgaBlue
);
assign led[15:1] = 14'b0;
assign dp = 1'b1;
wire clk_1Hz;
wire clk_vga;
wire clk_sevseg;
Clock_divider clock_divider_1Hz (
.clock_in(clk),
.clock_out(clk_1Hz)
);
Clock_divider #(.CLOCK_RATIO(100_000_000/250)) clock_divider_sevseg (
.clock_in(clk),
.clock_out(clk_sevseg)
);
Clock_divider #(.CLOCK_RATIO(100_000_000/50_000_000)) clock_divider_vga (
.clock_in(clk),
.clock_out(clk_vga)
);
Blinky blinky (
.clock(clk),
.clock_en(clk_1Hz),
.led(led[0])
);
reg [13:0] counter;
wire [1:0] seven_segment_sel;
always @(posedge clk) begin
if(clk_1Hz)
counter <= counter + 1;
end
Seven_segment_timing seven_segment_timing (
.clock(clk),
.clock_en(clk_sevseg),
.sel(seven_segment_sel),
.an(an)
);
Seven_segment_bcd seven_segment_bcd (
.clock(clk),
.value(counter),
.sel(seven_segment_sel),
.seg(seg)
);
wire [9:0] vga_x, vga_y;
wire vga_blank;
VGA_timing vga_timing (
.clock(clk),
.clock_en(clk_vga),
.hsync(Hsync),
.vsync(Vsync),
.blank(vga_blank),
.x(vga_x),
.y(vga_y)
);
RAM #(.WIDTH(12), .SIZE(400*300), .INIT_FILENAME("../init/vram.init")) ram (
.clock(clk),
.reset(vga_blank),
.clock_en(clk_vga),
.addr(400*vga_y[9:1]+vga_x[9:1]),
.din(12'b0),
.dout({vgaRed, vgaGreen, vgaBlue})
);
endmodule

21
rtl/Bin2bcd.v Normal file
View File

@@ -0,0 +1,21 @@
// parametric Verilog implementation of the double dabble binary to BCD converter
// for the complete project, see
// https://github.com/AmeerAbdelhadi/Binary-to-BCD-Converter
module Bin2bcd
#( parameter W = 18) // input width
( input [W-1 :0] bin , // binary
output reg [W+(W-4)/3:0] bcd ); // bcd {...,thousands,hundreds,tens,ones}
integer i,j;
always @(bin) begin
for(i = 0; i <= W+(W-4)/3; i = i+1) bcd[i] = 0; // initialize with zeros
bcd[W-1:0] = bin; // initialize with input vector
for(i = 0; i <= W-4; i = i+1) // iterate on structure depth
for(j = 0; j <= i/3; j = j+1) // iterate on structure width
if (bcd[W-i+4*j -: 4] > 4) // if > 4
bcd[W-i+4*j -: 4] = bcd[W-i+4*j -: 4] + 4'd3; // add 3
end
endmodule

16
rtl/Blinky.v Normal file
View File

@@ -0,0 +1,16 @@
module Blinky (
input clock,
input clock_en,
output reg led
);
initial begin
led <= 1'b0;
end
always @(posedge clock) begin
if(clock_en)
led <= ~led;
end
endmodule

20
rtl/Clock_divider.v Normal file
View File

@@ -0,0 +1,20 @@
module Clock_divider #(
parameter CLOCK_RATIO = 100_000_000
) (
input clock_in,
output reg clock_out
);
reg [$clog2(CLOCK_RATIO)-1:0] counter;
initial begin
clock_out = 1'b0;
counter = 0;
end
always @(posedge clock_in) begin
clock_out <= (counter >= CLOCK_RATIO-1);
counter <= (counter >= CLOCK_RATIO-1 ? 0 : counter + 1);
end
endmodule

33
rtl/RAM.v Normal file
View File

@@ -0,0 +1,33 @@
module RAM #(
parameter WIDTH = 8,
parameter SIZE = 128,
parameter INIT_FILENAME = ""
) (
input clock,
input reset,
input clock_en,
input write_en,
input [$clog2(SIZE)-1:0] addr,
input [WIDTH-1:0] din,
output reg [WIDTH-1:0] dout
);
reg [WIDTH-1:0] ram[SIZE-1:0], dout;
integer i;
initial begin
if(INIT_FILENAME == "")
for(i = 0; i < SIZE; i=i+1) ram[i] = 0;
else
$readmemb(INIT_FILENAME, ram);
end
always @(posedge clock) begin
if(clock_en) begin
dout <= reset ? 0 : ram[addr];
if(write_en)
ram[addr] <= din;
end
end
endmodule

39
rtl/Seven_segment_bcd.v Normal file
View File

@@ -0,0 +1,39 @@
module Seven_segment_bcd(
input clock,
input [13:0] value,
input [1:0] sel,
output reg [6:0] seg
);
wire [17:0] bcd;
wire [3:0] bcd_digit;
initial begin
seg = 0;
end
Bin2bcd #(.W(14)) bin2bcd (
.bin(value),
.bcd(bcd)
);
assign bcd_digit = bcd[4*sel +: 4];
always @(posedge clock) begin
case(bcd_digit)
// GFEDCBA
4'd0: seg <= 7'b1000000;
4'd1: seg <= 7'b1111001;
4'd2: seg <= 7'b0100100;
4'd3: seg <= 7'b0110000;
4'd4: seg <= 7'b0011001;
4'd5: seg <= 7'b0010010;
4'd6: seg <= 7'b0000010;
4'd7: seg <= 7'b1011000;
4'd8: seg <= 7'b0000000;
4'd9: seg <= 7'b0010000;
default: seg <= 7'bx;
endcase
end
endmodule

View File

@@ -0,0 +1,19 @@
module Seven_segment_timing (
input clock,
input clock_en,
output reg [1:0] sel,
output reg [3:0] an
);
initial begin
sel = 0;
an = 0;
end
always @(posedge clock) begin
an <= ~(4'b0001 << sel);
if(clock_en)
sel <= sel + 1;
end
endmodule

47
rtl/VGA_timing.v Normal file
View File

@@ -0,0 +1,47 @@
module VGA_timing #(
// VESA 800x600@72 use with 50MHz pixel clock
parameter H_VISIBLE = 800, // Visible area
parameter H_FRONT = 56, // Front porch
parameter H_SYNC = 120, // Sync pulse
parameter H_BACK = 64, // Back porch
parameter H_TOTAL = 1040, // Whole line
parameter V_VISIBLE = 600, // Visible area
parameter V_FRONT = 37, // Front porch
parameter V_SYNC = 6, // Sync pulse
parameter V_BACK = 23, // Back porch
parameter V_TOTAL = 666 // Whole line
) (
input clock,
input clock_en,
output reg hsync,
output reg vsync,
output reg blank,
output reg [$clog2(H_TOTAL)-1:0] x,
output reg [$clog2(V_TOTAL)-1:0] y
);
initial begin
hsync <= 1'b0;
vsync <= 1'b0;
blank <= 1'b0;
x <= 0;
y <= 0;
end
always @(posedge clock) begin
if(clock_en) begin
hsync <= ~(H_VISIBLE + H_FRONT <= x && x < H_VISIBLE + H_FRONT + H_SYNC);
vsync <= ~(V_VISIBLE + V_FRONT <= y && y < V_VISIBLE + V_FRONT + V_SYNC);
blank <= (H_VISIBLE-1 <= x && x < H_VISIBLE-1 + H_FRONT+H_SYNC+H_BACK)
|| (V_VISIBLE-1 <= y && y < V_VISIBLE-1 + V_FRONT+V_SYNC+V_BACK);
//blank <= (x >= H_VISIBLE-1 || y >= V_VISIBLE-1);
if(x >= H_TOTAL-1) begin
x <= 0;
y <= (y >= V_TOTAL-1) ? 0 : y + 1;
end else
x <= x + 1;
end
end
endmodule