Final project - Arbiter module
Code
`timescale 1ns/1ps
module arbiter (
input wire clk, // Clock
input wire rst_n, // Reset (active low)
input wire data_in1, // 1-bit input, player 1
input wire data_in2, // 1-bit input, player 2
output reg data_out, // 1-bit output, HIGH when first player wins, LOW otherwise
output reg finish // 1 bit output, HIGH when at least one players cross the finish line
);
// State encoding
parameter IDLE = 2'b00;
parameter L1_WIN = 2'b01;
parameter L2_WIN = 2'b10;
reg [1:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
always @(*) begin
next_state = state;
data_out = 0;
finish = 0;
case (state)
IDLE: begin
if (data_in1 == 1 && data_in2 == 1)
next_state = L1_WIN; // Tie-breaker: Lane 1 wins
else if (data_in1 == 1)
next_state = L1_WIN;
else if (data_in2 == 1)
next_state = L2_WIN;
else begin
data_out = 0;
finish = 0;
next_state = IDLE;
end
end
L1_WIN: begin
data_out = 1;
finish = 1;
// Stay in this state until reset
end
L2_WIN: begin
data_out = 0;
finish = 1;
// Stay in this state until reset
end
default: next_state = IDLE;
endcase
end
endmodule
Lint
verilator --lint-only -Wall -Ilib puf/arbiter.v
- V e r i l a t i o n R e p o r t: Verilator 5.044 2026-01-01 rev v5.044
- Verilator: Built from 0.032 MB sources in 2 modules, into 0.018 MB in 3 C++ files needing 0.000 MB
- Verilator: Walltime 0.007 s (elab=0.000, cvt=0.003, bld=0.000); cpu 0.007 s on 1 threads; alloced 30.352 MB
Test harness
`timescale 1ns/1ps
module test_arbiter;
// Inputs are reg (we drive them)
reg clk, rst_n, data_in1, data_in2;
// Outputs are wire (DUT drives them)
wire data_out, finish;
// Instantiate Device Under Test
arbiter arbiter (
.clk(clk),
.rst_n(rst_n),
.data_in1(data_in1),
.data_in2(data_in2),
.data_out(data_out),
.finish(finish)
);
// Clock generation
always #10 clk = ~clk; // 50 MHz (20ns period)
// Test stimulus
initial begin
$dumpfile("waves.vcd");
$dumpvars(0, test_arbiter);
// Initialize
$display("Initialize");
#10
clk = 0;
display;
// Reset
$display("----------- Reset --------------");
rst_n = 0;
data_in1 = 0;
data_in2 = 0;
#20
rst_n = 1;
#20
$display("----------------- --------------");
// Test case 1
$display("==> Test case 1: first player wins");
data_in1 = 1;
#20
$display("Second player follows");
data_in2 = 1;
#20
display;
// Reset
$display(" --------- Reset --------------");
rst_n = 0;
data_in1 = 0;
data_in2 = 0;
#20
rst_n = 1;
#20
$display("----------------- --------------");
// Test case 2
$display("==> Test case 2: second player wins");
data_in2 = 1;
#20
$display("First player follows");
data_in1 = 1;
#20
display;
// Reset
$display(" --------- Reset --------------");
rst_n = 0;
data_in1 = 0;
data_in2 = 0;
#20
rst_n = 1;
#20
$display("----------------- --------------");
// Test case 2
$display("==> Test case 3: both wins... player 1 is picked");
data_in2 = 1;
data_in1 = 1;
#20
display;
// Reset
$display(" --------- Reset --------------");
rst_n = 0;
data_in1 = 0;
data_in2 = 0;
#20
rst_n = 1;
#20
$display("----------------- --------------");
#100
$finish;
end
task display;
#1 $display("data_in1:%0h, data_in2:%0h, data_out:%0h, finish:%0h, reset:%0h",
data_in1, data_in2, data_out, finish, rst_n);
endtask
endmodule
Test run in simulation
Initialize
data_in1:x, data_in2:x, data_out:x, finish:x, reset:x
----------- Reset --------------
----------------- --------------
==> Test case 1: first player wins
Second player follows
data_in1:1, data_in2:1, data_out:1, finish:1, reset:1
--------- Reset --------------
----------------- --------------
==> Test case 2: second player wins
First player follows
data_in1:1, data_in2:1, data_out:0, finish:1, reset:1
--------- Reset --------------
----------------- --------------
==> Test case 3: both wins... player 1 is picked
data_in1:1, data_in2:1, data_out:1, finish:1, reset:1
--------- Reset --------------
----------------- --------------
puf/test_arbiter.v:100: $finish called at 374000 (1ps)