Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

ELEC0010 Examples of SystemVerilog modules describing digital building blocks

Contents

1. D-flip flops

2. Register

3. Register file

4. Read only memory (ROM)

5. Arithmetic logic unit

6. Counter

7. Testbench to test register module

1. D-flip flops

 

The example code below implements a D-flip flop with active positive clock edge and active- high synchronous reset (the flip flop resets only when a positive clock edge is applied).

module dff (input logic data_in, reset, clk,

output logic q, q_bar);

assign q_bar = ~q;

always_ff @ (posedge clk)

begin

if (reset) q <= 0;

else q <= data_in;

end

endmodule

The example code below implements a D-flip flop with active positive clock edge and active- high asynchronous reset (the flip flop resets whenever the reset input is asserted).

module dff (input logic data_in, reset, clk,

output logic q, q_bar);

assign q_bar = ~q;

always_ff @ (posedge clk or posedge reset)

begin

if (reset) q <= 0;

else q <= data_in;

end

endmodule

2. Register

The following code describes an 8-bit register:

module regist (input logic [7:0] data_in,

input logic clk,

output logic [7:0] data_out);

always_ff @ (posedge clk)

data_out <= data_in;

endmodule

3. Register file

 

This register file has sixteen 8-bit registers. The contents of any two of the registers (with addresses specified by the 4-bit inputs RA1 and RA2) are continuously output as data_out1 and data_out2. On the positive edge of the clock , if write_enable is asserted, the input data_in is written into the register at address WA.

module reg_file(input logic [3:0] RA1, RA2, WA,

input logic [7:0] data_in,

input logic clk, reset, write_enable,

output logic [7:0] data_out1, data_out2);

logic [7:0] rf [0:15];

assign data_out1 = rf[RA1];

assign data_out2 = rf[RA2];

always_ff @ (posedge clk)

if (write_enable)

rf[WA] <= data_in;

endmodule

4. Arithmetic logic unit (ALU)

 

This example of an ALU carries out bitwise logical operations, addition and subtraction operations, according to the table below.

 

module alu(input logic [7:0] a,

input logic [7:0] b,

output logic [7:0] ALUResult,

input logic [2:0] ALUControl);

always_comb

case(ALUControl)

3'b000 : ALUResult = a & b; // bitwise a AND b

3'b001 : ALUResult = a | b; // bitwise a OR b

3'b010 : ALUResult = a + b; // addition a + b

3'b100 : ALUResult = a & ~b; // bitwise a AND (NOT b)

3'b101 : ALUResult = a | ~b; // bitwise a OR (NOT b)

3'b110 : ALUResult = a - b; // subtraction a - b

default : ALUResult = 8'bx;

endcase

endmodule

The arithmetic operations assume negative values are represented in two’s complement. The most significant bit indicates the sign of the number (0 for positive numbers, 1 for negative numbers). Conversion between positive and negative values is carried out by inverting the bits, and adding one.

Example - represent -4510 in 8-bit two’s complement form:

•    Start with the representation of +4510 : 00101101.

•    Invert the bits and add 1: -4510 = 11010011

5. Read-Only Memory (ROM) array

 

The synthesisable code example below implements a ROM array, storing 16 words of data, with each word being 8 bits wide. The data to be stored is read in from a text file, in a single pass behaviour (keyword initial), using the $readmemh system task. In the example below, the text file name ‘rom.txt’ has been chosen; any file name ‘*.txt’, without spaces, can be used. The text file should be stored in the same folder as the SystemVerilog modules.

module rom(input logic [3:0] address,

output logic [7:0] data_out);

logic [7:0] data_ROM [0:15];

initial

$readmemh(“rom.txt”, data_rom);

assign data_out = data_ROM[address];

endmodule

Shown below is an example of the text file rom.txt’ containing the 16 words of data (each word is 8-bits wide) to be stored in the ROM. The data is written in hexadecimal form:

02

E4

75

2A

CE

35

D1

97

56

F2

A4

B0

01

89

F5

A7

Note: The values in the text file could alternatively be written in binary rather than hexadecimal; in this case, the system task $readmemb should then be used in the ROM module.

6. Counter

The following describes an 8-bit counter with active-high reset. The value of count increments on each rising edge of the clock.

module counter(input logic clk, reset,

output logic [7:0] count);

always_ff @ (posedge clk) begin

if (reset) count <= 8'b0;

else count <= count + 1;

end

endmodule

7. Testbench

The following is an example of a testbench to the test the register file module in section 3:

`timescale 1ps/1ps

`include "reg_file.sv"

module reg_file_tb;

logic [3:0] RA1, RA2, WA;

logic clk, reset, write_enable;

logic [7:0] data_in, data_out1, data_out2;

reg_file dut (RA1, RA2, WA, data_in, clk, reset, write_enable, data_out1, data_out2);

initial begin // Generate clock signal with 20 ns period

clk = 0;

forever #10 clk = ~clk;

end

initial begin // Apply stimulus

$dumpfile("reg_file_tb.vcd");

$dumpvars(0, reg_file_tb);

RA1 = 1; RA2 = 2; WA = 0; data_in = 5; write_enable = 0;

reset = 1;

#10 reset = 0;

#15 write_enable = 1;

#20 WA = 1; data_in = 7;

#20 WA = 5; data_in = 13;

#20 write_enable = 0;

#20 RA2 = 5;

#30;

$finish; // This system tasks ends the simulation

end

initial begin // Response monitor

$monitor ("t = %3d, clk = %b, reset = %b, RA1 = %b RA2 = %b, \

WA = %b, write_enable = %b, data_in = %b, data_out1 = %b, \

data_out2 = %b", $time, clk, reset, RA1, RA2, WA, write_enable, data_in, data_out1, data_out2);

end

endmodule

Note that  a  string  literal  can  be  extended  onto the  next  line,  provided  the  new  line  is immediately preceded by a \ (backslash). This is used in the response monitor block in the above example, to make the code more readable in the source code editor.

The resulting simulation waveforms from the reg_file_tb testbench are shown below.