0% found this document useful (0 votes)
1 views4 pages

LAB8

The document contains Verilog code for three modules: a multiplexer (MUX8_1), a timer with 7-segment display output, and a serial output generator. The timer module includes logic for counting seconds and minutes, with start/pause and reset functionality, while the serial output module generates a sequence of characters. Additionally, there is a testbench for the serial output module to verify its functionality.

Uploaded by

cracial11011
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views4 pages

LAB8

The document contains Verilog code for three modules: a multiplexer (MUX8_1), a timer with 7-segment display output, and a serial output generator. The timer module includes logic for counting seconds and minutes, with start/pause and reset functionality, while the serial output module generates a sequence of characters. Additionally, there is a testbench for the serial output module to verify its functionality.

Uploaded by

cracial11011
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

CAU1//////////////////

module MUX8_1(
input wire KEY0, KEY1, KEY2,
input wire [7:0]SW,
output wire LED0
);

assign LED0= (SW[7]&~KEY2&~KEY1&~KEY0)|(SW[6]&~KEY2&~KEY1&KEY0)|


(SW[5]&~KEY2&KEY1&~KEY0)|(SW[4]&~KEY2&KEY1&KEY0)|(SW[3]&KEY2&~KEY1&~KEY0)|
(SW[2]&KEY2&~KEY1&KEY0)|(SW[1]&KEY2&KEY1&~KEY0)
|(SW[0]&KEY2&KEY1&KEY0);

endmodule

CAU3//////////////
module MUX8_1 (
input wire clk_50MHz,
input wire KEY0, // Start/Pause (active-low)
input wire KEY1, // Reset (active-low)
output wire [0:6] HEX3, // Minutes tens
output wire [0:6] HEX2, // Minutes ones
output wire [0:6] HEX1, // Seconds tens
output wire [0:6] HEX0 // Seconds ones
);

// Invert buttons (active-low)


wire btn_start_raw = ~KEY0;
wire btn_reset_raw = ~KEY1;

// Clock divider: 50MHz -> 1Hz


reg [25:0] clk_div;
wire clk_1Hz;

always @(posedge clk_50MHz) begin


if (clk_div == 49999999)
clk_div <= 0;
else
clk_div <= clk_div + 1;
end

assign clk_1Hz = (clk_div == 49999999);

// Debounce and edge detection


reg [19:0] debounce_start, debounce_reset;
reg btn_start_clean, btn_reset_clean;
reg btn_start_prev, btn_reset_prev;

always @(posedge clk_50MHz) begin


// Debounce start
if (btn_start_raw) begin
if (debounce_start < 999999)
debounce_start <= debounce_start + 1;
else
btn_start_clean <= 1;
end else begin
debounce_start <= 0;
btn_start_clean <= 0;
end
// Debounce reset
if (btn_reset_raw) begin
if (debounce_reset < 999999)
debounce_reset <= debounce_reset + 1;
else
btn_reset_clean <= 1;
end else begin
debounce_reset <= 0;
btn_reset_clean <= 0;
end

// Edge detection
btn_start_prev <= btn_start_clean;
btn_reset_prev <= btn_reset_clean;
end

wire btn_start_edge = btn_start_clean & ~btn_start_prev;


wire btn_reset_edge = btn_reset_clean & ~btn_reset_prev;

// Timer logic
reg [3:0] sec_ones, sec_tens, min_ones, min_tens;
reg is_running;

always @(posedge clk_50MHz) begin


if (btn_start_edge)
is_running <= ~is_running;

if (btn_reset_edge) begin
sec_ones <= 0;
sec_tens <= 0;
min_ones <= 0;
min_tens <= 0;

// Nếu đang chạy thì tiếp tục chạy, nếu đang dừng thì vẫn dừng
// Không thay đổi is_running
end else if (is_running && clk_1Hz) begin
// Dừng khi đạt 10:00
if (min_tens == 1 && min_ones == 0 && sec_tens == 0 && sec_ones == 0)
is_running <= 0;
else begin
sec_ones <= sec_ones + 1;
if (sec_ones == 9) begin
sec_ones <= 0;
sec_tens <= sec_tens + 1;
if (sec_tens == 5) begin
sec_tens <= 0;
min_ones <= min_ones + 1;
if (min_ones == 9) begin
min_ones <= 0;
min_tens <= min_tens + 1;
end
end
end
end
end
end

// 7-segment decoder (active-low)


function [0:6] digit_to_7seg;
input [3:0] digit;
begin
case (digit)
4'd0: digit_to_7seg = 7'b0000001;
4'd1: digit_to_7seg = 7'b1001111;
4'd2: digit_to_7seg = 7'b0010010;
4'd3: digit_to_7seg = 7'b0000110;
4'd4: digit_to_7seg = 7'b1001100;
4'd5: digit_to_7seg = 7'b0100100;
4'd6: digit_to_7seg = 7'b0100000;
4'd7: digit_to_7seg = 7'b0001111;
4'd8: digit_to_7seg = 7'b0000000;
4'd9: digit_to_7seg = 7'b0000100;
default: digit_to_7seg = 7'b1111111;
endcase
end
endfunction

assign HEX3 = digit_to_7seg(min_tens);


assign HEX2 = digit_to_7seg(min_ones);
assign HEX1 = digit_to_7seg(sec_tens);
assign HEX0 = digit_to_7seg(sec_ones);

endmodule

CAU2///////////////////////////////////////
module serial_output (
input wire clk,
input wire reset,
output reg [7:0] data
);

reg [2:0] counter;

always @(posedge clk) begin


if (reset) begin
counter <= 0;
data <= 8'h51; // 'Q'
end else begin
case (counter)
3'd0: data <= 8'h51; // 'Q'
3'd1: data <= 8'h75; // 'u'
3'd2: data <= 8'h61; // 'a'
3'd3: data <= 8'h6E; // 'n'
3'd4: data <= 8'h67; // 'g'
3'd5: data <= 8'h65; // end
default: data <= 8'h65;
endcase

if (counter < 5) begin


counter <= counter + 1;
end else begin
counter <= 0; // Lặp lại
end
end
end

endmodule
testbench////////////////////////////////////
`timescale 1ns/1ps

module tb_serial_output;

reg clk, reset;


wire [7:0] data;

serial_output uut (
.clk(clk),
.reset(reset),
.data(data)
);

// Clock 10ns
always #5 clk = ~clk;

initial begin
clk = 0;
reset = 0;

$display("=== Test Serial Output - Name: Quang ===");


$monitor("Time=%0t | Reset=%b | Data=0x%h (%c)", $time, reset, data, data);

// Test 1: Reset đầu mô phỏng


reset = 1; #10;
reset = 0; #10;

// Test 2: Hoạt động bình thường (xuất hết chuỗi)


#50; // 5 chu kỳ để xuất hết "Quang" + end

// Test 3: Reset sau khi xuất > 1/2 chuỗi (sau 3 ký tự)
#30; // Thêm 3 chu kỳ nữa
reset = 1; #10;
reset = 0;

// Tiếp tục để xem reset hoạt động


#40;

$finish;
end

endmodule

You might also like