Merge branch 'wcude'

This commit is contained in:
2025-05-19 15:22:32 -07:00
8 changed files with 223 additions and 25 deletions
+11
View File
@@ -0,0 +1,11 @@
// NOTE: This expects to be driven with a 100khz clock
module display_anode_driver(input logic clk, input logic reset, output logic [7:0] AN);
// This is just a shift register that drives each anode individually
always_ff @(posedge clk) begin
if (reset)
AN <= 1;
else
AN <= {AN[6:0], AN[7]};
end
endmodule
+45
View File
@@ -0,0 +1,45 @@
`include "sdvd_defs.sv"
import sdvd_defs::SPEED;
// Takes in a 100MHz clock and generates the very low freq signals needed
// for driving the control logic
module low_freq_clock_gen(
input logic clk, reset,
input SPEED speed,
output logic clk1k, clk10h, seconds_pulse
);
logic [$clog2(100_000_000):0] counter;
logic [$clog2(4000):0] seconds_counter;
logic clk4k;
assign clk1k = (counter % (100_000_000/1000)) != 0;
assign clk10h = (counter % (100_000_000/10)) != 0;
assign clk4k = (counter % (100_000_000/4000)) != 0;
always_ff @(posedge clk) begin
// NOTE: This generates a pulse on the same clock cycle that reset is
// asserted. Is that bad??
if (reset)
counter <= 0;
// Roll the counter over back to zero every second
else if (counter == 99_999_999)
counter <= 0;
else
counter <= counter + 1;
// This logic handles the variable-speed seconds counter
if (reset) begin
seconds_pulse <= 0;
seconds_counter <= 0;
end
else if (clk4k && seconds_counter >= 4000) begin
seconds_counter <= seconds_counter-4000;
seconds_pulse <= 1;
end
else if (clk4k) begin
seconds_pulse <= 0;
seconds_counter <= seconds_counter + {9'b0, speed};
end
end
endmodule
+67
View File
@@ -0,0 +1,67 @@
`include "sdvd_defs.sv"
import sdvd_defs::SPEED;
module nexys_a7_top(
input logic CLK100MHZ, CPU_RESETN,
input logic BTNC, BTNR,
output logic [7:0] CA,CB,CC,CD,CE,CF,CG,
output logic [7:0] AN
);
// Active high reset
wire reset;
assign reset = ~CPU_RESETN;
logic clk_1khz, clk_10hz;
logic seconds_pulse;
SPEED speed;
// Map C{A-G} to an array of 7-segment displays
wire [6:0] segments [7:0];
for (genvar i = 0; i<8; i++) begin: segmentGenerate
assign {CG[i],CF[i],CE[i],CD[i],CC[i],CB[i],CA[i]} = segments[i];
end
logic [$clog2(60):0] seconds;
logic [$clog2(60):0] minutes;
logic [$clog2(60):0] hours;
low_freq_clock_gen clockGen(CLK100MHZ, reset, speed, clk_1khz, clk_10hz, seconds_pulse);
// Count the number on seconds, hours, and minutes elapsed
// If the speed is faster this will pulse more often than once a second
// but will still theoretically be a second of video time
always_ff @(posedge seconds_pulse) begin
if (reset) begin
seconds <= 0;
minutes <= 0;
hours <= 0;
end
else if (seconds == 59) begin
seconds <= 0;
if (minutes == 59) begin
minutes <= 0;
hours <= hours + 1;
end
else
minutes <= minutes + 1;
end
else
seconds <= seconds + 1;
end
display_anode_driver anodeDriver(clk_1khz,reset,AN);
seconds_display secondsSegment (seconds, segments[1], segments[0]);
seconds_display minutesSegment (minutes, segments[3], segments[2]);
seconds_display hoursSegment (hours, segments[5], segments[4]);
// Run the playback speed state machine at a lower rate
// Gets rid of button bouncing
playback_controller playbackController (clk_10hz,reset,BTNC, BTNR, speed);
endmodule
+5 -2
View File
@@ -1,4 +1,7 @@
module Playback_Controller(
`include "sdvd_defs.sv"
import sdvd_defs::SPEED;
module playback_controller(
// This clock should be reasonably slow
input logic clk,
input logic reset,
@@ -8,7 +11,7 @@ module Playback_Controller(
input logic ff,
// Output is 0, 1x, 2x, 4x, or 8x
output wire [3:0] speed
output SPEED speed
);
wire play_pulse,ff_pulse;
+7
View File
@@ -0,0 +1,7 @@
`ifndef SDVD_DEFS
`define SDVD_DEFS
package sdvd_defs;
// Playback speed type
typedef logic [3:0] SPEED;
endpackage
`endif