78 lines
2.4 KiB
Systemverilog
78 lines
2.4 KiB
Systemverilog
// sample.sv - SystemVerilog fixture for parser tests
|
|
`timescale 1ns / 1ps
|
|
|
|
// File-level package import
|
|
import utils_pkg::*;
|
|
|
|
// Interface declaration
|
|
interface BusIf #(parameter int WIDTH = 8);
|
|
logic [WIDTH-1:0] data;
|
|
logic valid;
|
|
logic ready;
|
|
modport master(output data, valid, input ready);
|
|
modport slave(input data, valid, output ready);
|
|
endinterface
|
|
|
|
// Submodule to be instantiated by FIFOController
|
|
module Adder #(parameter int WIDTH = 8) (input logic [WIDTH-1:0] a, b, output logic [WIDTH-1:0] sum);
|
|
assign sum = a + b;
|
|
endmodule
|
|
|
|
// Main module with tasks, functions, always blocks, and module instantiation
|
|
// Parameters on one line to avoid grammar parse errors
|
|
module FIFOController #(parameter int DEPTH = 16, parameter int WIDTH = 8) (
|
|
input logic clk,
|
|
input logic rst_n,
|
|
input logic [WIDTH-1:0] data_in,
|
|
input logic wr_en,
|
|
input logic rd_en,
|
|
output logic [WIDTH-1:0] data_out,
|
|
output logic full,
|
|
output logic empty
|
|
);
|
|
|
|
// Intra-module package import
|
|
import arith_pkg::counter_t;
|
|
|
|
logic [WIDTH-1:0] mem [0:DEPTH-1];
|
|
logic [$clog2(DEPTH):0] wr_ptr, rd_ptr, count;
|
|
|
|
// Module instantiation - creates CALLS edge from FIFOController to Adder
|
|
Adder #(.WIDTH(WIDTH)) ptr_adder (.a(wr_ptr[WIDTH-1:0]), .b(rd_ptr[WIDTH-1:0]), .sum());
|
|
|
|
// Task declaration
|
|
task automatic do_write(input logic [WIDTH-1:0] din);
|
|
mem[wr_ptr] <= din;
|
|
wr_ptr <= wr_ptr + 1;
|
|
count <= count + 1;
|
|
endtask
|
|
|
|
// Function declaration
|
|
function automatic logic is_full();
|
|
return (count >= DEPTH);
|
|
endfunction
|
|
|
|
// Always block (sequential logic) - flattened to avoid nested begin/end
|
|
// grammar limitation: if(x) begin..end inside else begin..end causes parse errors
|
|
always_ff @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
wr_ptr <= 0;
|
|
rd_ptr <= 0;
|
|
count <= 0;
|
|
end
|
|
if (rst_n && wr_en && !full) do_write(data_in);
|
|
if (rst_n && rd_en && !empty) begin
|
|
data_out <= mem[rd_ptr];
|
|
rd_ptr <= rd_ptr + 1;
|
|
count <= count - 1;
|
|
end
|
|
end
|
|
|
|
// Always block (combinational logic)
|
|
always_comb begin
|
|
full = is_full();
|
|
empty = (count == 0);
|
|
end
|
|
|
|
endmodule
|