EECS151 / fpga_labs_fa20 / lab4 / src / music_streamer.v
music_streamer.v
Raw
module music_streamer (
    input clk,
    input rst,
    input tempo_up,
    input tempo_down,
    input play_pause,
    input reverse,
    output [2:0] leds,
    output [23:0] tone
);
    wire [9:0] last_address;
    wire       reset, valid_change;

    reg [23:0] delay;
    reg  [9:0] address;
    reg [23:0] clk_counter;
    
    localparam [23:0] DELTA_TEMPO = 500_000; // 
    localparam [23:0] BASE_DELAY = 5_000_000; // 1/25 sec/tone
    localparam [23:0] MAX_DELAY = ~0 - BASE_DELAY; // prevent overflow

    rom memory (.address(address),
                .data(tone),
                .last_address(last_address)
               );
   
    // Ensures changing tempo doesn't cause problems
    assign valid_change = (delay > DELTA_TEMPO) && (delay < MAX_DELAY);
    assign reset = (rst || address == last_address);

    // Control notes being played
    always @(posedge clk) begin  
        if (reset) begin
            address <= 0;
            clk_counter <= 0; 
        end else if (clk_counter == delay) begin
            address <= address + 1;
            clk_counter <= 0; 
        end else
            clk_counter <= clk_counter + 1;
    end

    // Control tempo
    always @(posedge clk) begin
        if (rst)
            delay <= BASE_DELAY;
        else if (tempo_up && valid_change)
            delay <= delay - DELTA_TEMPO;
        else if (tempo_down && valid_change)
            delay <= delay + DELTA_TEMPO;
    end   

endmodule