Commit ae87e16c by root

add verilog testbench to gitlab

parent b06b4eb7

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

......@@ -16,8 +16,6 @@
**/tmp/
/data/*
/ret_one/*
/testbench/*
# Byte-compiled / optimized / DLL files
__pycache__/
......
......@@ -916,7 +916,7 @@ Example of expected response format:
print(f"STA command failed with error:\n{e.stderr}")
ppa["error"] = "STA error:\n" + e.stderr
return ppa
try:
with open(power_path, 'r') as f:
for line in f:
......
# Default constraints file that sets up clocks based on definitions in schema.
source sc_manifest.tcl > /dev/null
set current_dir [file normalize [file dirname [info script]]]
source [file join $current_dir "sc_manifest.tcl"]
### Create clocks
if { [sc_cfg_exists datasheet pin] } {
......
# Minimal sc_manifest.tcl for basic PPA analysis
# This file provides stub implementations for sc_cfg_* functions
# Define basic configuration functions as stubs
proc sc_cfg_exists {args} {
# Return false for all configuration checks
return 0
}
proc sc_cfg_get {args} {
# Return empty for all configuration requests
return {}
}
proc sc_cfg_tool_task_exists {args} {
# Return false for all tool task checks
return 0
}
proc sc_cfg_tool_task_get {args} {
# Return empty list for all tool task requests
return {}
}
# Define empty configuration dictionaries
set sc_cfg_dict {}
set sc_tool_dict {}
puts "sc_manifest.tcl loaded - basic stub mode for PPA analysis"
\ No newline at end of file
MIT License
Copyright (c) 2024 Nora Lu
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please act as a professional verilog designer.
Implement a 64-bit Johnson counter (torsional ring counter), and the state of the similar 4-bit Johnson counter example is as follows: 0000, 1000, 1100, 1110, 1111, 0111, 0011, 0001, 0000.
Module name:
JC_counter
Input ports:
clk: Clock signal used for synchronous operation.
rst_n: Active-low reset signal to initialize the counter.
Output port:
Q: 64-bit register representing the current count value.
Implementation:
On every rising edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the counter value is updated.
If the reset signal (rst_n) is low, indicating a reset condition, the counter value (Q) is set to 0.
Otherwise, if the least significant bit (Q[0]) is 0, the counter increments by shifting the current value (Q[63:1]) to the right and appending a 1 at the most significant bit position.
If the least significant bit (Q[0]) is 1, the counter decrements by shifting the current value (Q[63:1]) to the right and appending a 0 at the most significant bit position.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = JC_counter
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module JC_counter(
input clk ,
input rst_n,
output reg [63:0] Q
);
`timescale 1ns/1ns
module testbench;
// Parameters
parameter CLK_PERIOD = 10; // Clock period in simulation time units
// Inputs
reg clk;
reg rst_n;
// Outputs
wire [63:0] Q;
// Instantiate the module
JC_counter uut (
.clk(clk),
.rst_n(rst_n),
.Q(Q)
);
// Clock generation
always #((CLK_PERIOD)/2) clk = ~clk;
integer error=0;
// Initial block for stimulus generation
initial begin
// Initialize inputs
clk = 0;
rst_n = 1;
// Wait for a few clock cycles
#((CLK_PERIOD) * 2);
// Release reset
rst_n = 0;
#((CLK_PERIOD) * 2);
rst_n = 1;
// Simulate for a number of clock cycles
#((CLK_PERIOD) * 20);
error = (Q ==64'b 1111111111111111111100000000000000000000000000000000000000000000)? error : error+1;
#((CLK_PERIOD) * 44);
error = (Q ==64'b 1111111111111111111111111111111111111111111111111111111111111111)? error : error+1;
#((CLK_PERIOD) * 1);
error = (Q ==64'b 0111111111111111111111111111111111111111111111111111111111111111)? error : error+1;
#((CLK_PERIOD) * 62);
error = (Q ==64'b 0000000000000000000000000000000000000000000000000000000000000001)? error : error+1;
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Error===========");
end
// $display("Q = %b", Q);
// Finish simulation
$finish;
end
endmodule
`timescale 1ns/1ns
module verified_JC_counter(
input clk ,
input rst_n,
output reg [63:0] Q
);
always@(posedge clk or negedge rst_n)begin
if(!rst_n) Q <= 'd0;
else if(!Q[0]) Q <= {1'b1, Q[63 : 1]};
else Q <= {1'b0, Q[63 : 1]};
end
endmodule
Please act as a professional verilog designer.
Implement a dual-port RAM with a depth of 8 and a bit width of 6 bits, with all data initialized to 000000. It has two groups of ports, respectively for reading data and writing data, and read and write operations can be carried out at the same time. When the read_en signal is 1, the read_data of the corresponding position is read through the read_addr signal and output; When the write_en signal is 1, data is written to the corresponding position through the write_addr signal and write-data signal.
Module name:
RAM
Input ports:
clk: Clock signal used for synchronous operation.
rst_n: Active-low reset signal. Defined as 0 for reset and 1 for reset signal inactive.
write_en: Write enable signal to initiate a write operation.
write_addr: Address for the write operation.
write_data: Data to be written to the RAM.
read_en: Read enable signal to initiate a read operation.
read_addr: Address for the read operation.
Output ports:
read_data: Output signal representing the data read from the RAM.
Parameter:
WIDTH = 6;
DEPTH = 8;
Implementation:
RAM Array:
The module includes a register array, RAM. The array is defined as reg [DEPTH - 1 : 0] RAM [2**WIDTH-1:0], allowing for 2^6 memory locations, each with a width of 6 bits.
Write Operation:
The first always block triggers on the positive edge of the clock signal (posedge clk) or the negative edge of the reset signal (negedge rst_n).
On reset, indicated by !rst_n, all memory locations in the RAM array are cleared to 0.
If the write enable signal (write_en) is active, the data (write_data) is written to the RAM array at the specified address (write_addr).
Read Operation:
The second always block triggers on the positive edge of the clock signal (posedge clk) or the negative edge of the reset signal (negedge rst_n).
On reset, indicated by !rst_n, the read_data register is cleared to 0.
If the read enable signal (read_en) is active, the data at the specified address (read_addr) in the RAM array is assigned to the read_data register.
If the read enable signal is not active, the read_data register is cleared to 0.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = RAM
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module RAM (
input clk,
input rst_n,
input write_en,
input [7:0]write_addr,
input [5:0]write_data,
input read_en,
input [7:0]read_addr,
output reg [5:0]read_data
);
`timescale 1ns/1ns
module tb_RAM;
// Parameters
parameter CLK_PERIOD = 10; // Clock period in simulation time units
// Inputs
reg clk;
reg rst_n;
reg write_en;
reg [7:0] write_addr;
reg [5:0] write_data;
reg read_en;
reg [7:0] read_addr;
// Outputs
wire [5:0] read_data;
// Instantiate the module
RAM uut (
.clk(clk),
.rst_n(rst_n),
.write_en(write_en),
.write_addr(write_addr),
.write_data(write_data),
.read_en(read_en),
.read_addr(read_addr),
.read_data(read_data)
);
// Clock generation
always #((CLK_PERIOD)/2) clk = ~clk;
integer error = 0;
// Initial block for stimulus generation
initial begin
// Initialize inputs
clk = 0;
rst_n = 1;
repeat(100) begin
write_en = 0;
write_addr = 0;
write_data = 0;
read_en = 0;
read_addr = 0;
// Wait for a few clock cycles
#((CLK_PERIOD) * 5);
// Release reset
rst_n = 0;
#((CLK_PERIOD) * 2);
rst_n = 1;
// Write operation
write_en = 1;
write_addr = 3'b000;
write_data = $random;
#((CLK_PERIOD) * 1);
write_en = 0;
#((CLK_PERIOD) * 1);
// Read operation
read_en = 1;
read_addr = 3'b000;
#((CLK_PERIOD) * 1);
// $display("read_data = %b", read_data);
error = (read_data == write_data) ? error : error+1;
read_en = 0;
#((CLK_PERIOD) * 1);
// $display("read_data = %b", read_data);
error = (read_data == 0) ? error : error+1;
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Error===========", error);
end
// Finish simulation
$finish;
end
endmodule
module verified_RAM (
input clk,
input rst_n,
input write_en,
input [7:0]write_addr,
input [5:0]write_data,
input read_en,
input [7:0]read_addr,
output reg [5:0]read_data
);
//defination
reg [7 : 0] RAM [11:0];
//output
integer i;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) begin
for(i = 0; i < 8; i = i + 1) begin
RAM[i] <= 'd0;
end
end
else if(write_en)
RAM[write_addr] <= write_data;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
read_data <= 'd0;
else if(read_en)
read_data <= RAM[read_addr];
else
read_data <= 'd0;
end
endmodule
Please act as a professional verilog designer.
Implement a module to achieve serial input data accumulation output, input is 8bit data. The valid_in will be set to 1 before the first data comes in. Whenever the module receives 4 input data, the data_out outputs 4 received data accumulation results and sets the valid_out to be 1 (will last only 1 cycle).
Module name:
accu
Input ports:
clk: Clock input for synchronization.
rst_n: Active-low reset signal.
data_in[7:0]: 8-bit input data for addition.
valid_in: Input signal indicating readiness for new data.
Output ports:
valid_out: Output signal indicating when 4 input data accumulation is reached.
data_out[9:0]: 10-bit output data representing the accumulated sum.
Implementation:
When valid_in is 1, data_in is a valid input. Accumulate four valid input data_in values and calculate the output data_out by adding these four values together.
There is no output when there are fewer than four data_in inputs in the interim. Along with the output data_out, a cycle of valid_out=1 will appear as a signal.
The valid_out signal is set to 1 when the data_out outputs 4 received data accumulation results. Otherwise, it is set to 0.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = accu
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module accu(
input clk ,
input rst_n ,
input [7:0] data_in ,
input valid_in ,
output reg valid_out ,
output reg [9:0] data_out
);
\ No newline at end of file
`timescale 1ns / 1ps
module tb_valid_ready;
parameter PERIOD = 10;
reg clk = 0 ;
reg rst_n = 0 ;
reg [7:0] data_in = 0 ;
reg valid_in = 0 ;
wire valid_out ;
wire [9:0] data_out ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
initial
begin
#(PERIOD*2) rst_n = 1;
end
accu uut (
.clk ( clk ),
.rst_n ( rst_n ),
.data_in ( data_in [7:0] ),
.valid_in ( valid_in ),
.valid_out ( valid_out ),
.data_out ( data_out [9:0] )
);
initial
begin
#(PERIOD*1+0.01);
#(PERIOD) data_in = 8'd1;valid_in = 1;
#(PERIOD) data_in = 8'd2;
#(PERIOD) data_in = 8'd3;
#(PERIOD) data_in = 8'd14;
#(PERIOD) data_in = 8'd5;
#(PERIOD) data_in = 8'd2;
#(PERIOD) data_in = 8'd103;
#(PERIOD) data_in = 8'd4;
#(PERIOD) data_in = 8'd5;
#(PERIOD) data_in = 8'd6;
#(PERIOD) data_in = 8'd3;
#(PERIOD) data_in = 8'd54;
#(PERIOD*2);
$finish;
end
reg [9:0] result [0:2];
initial begin
result[0] = 9'd20;
result[1] = 9'd114;
result[2] = 9'd68;
end
integer i;
integer casenum = 0;
integer error = 0;
initial
begin
for (i = 0; i < 15; i = i + 1) begin
#((PERIOD) * 1);
if (valid_out) begin
error = (data_out == result[casenum]) ? error : error + 1;
casenum = casenum + 1;
end
end
if(error==0 && casenum==3)
begin
$display("===========Your Design Passed===========");
end
else
begin
$display("===========Error===========");
end
$finish;
end
endmodule
`timescale 1ns/1ns
module verified_accu(
input clk ,
input rst_n ,
input [7:0] data_in ,
input valid_in ,
output reg valid_out ,
output reg [9:0] data_out
);
reg [1:0] count;
wire add_cnt;
wire ready_add;
wire end_cnt;
reg [9:0] data_out_reg;
assign add_cnt = ready_add;
assign end_cnt = ready_add && (count == 'd3);
//count
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
count <= 0;
end
else if(end_cnt) begin
count <= 0;
end
else if(add_cnt) begin
count <= count + 1;
end
end
//data_out_reg
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_out_reg <= 0;
end
else if (add_cnt && count == 0) begin
data_out_reg <= data_in;
end
else if (add_cnt) begin
data_out_reg <= data_out_reg + data_in;
end
end
//data_out
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_out <= 0;
end
else if (add_cnt && count == 0) begin
data_out <= data_in;
end
else if (add_cnt) begin
data_out <= data_out + data_in;
end
end
//ready_add
assign ready_add = !valid_out | valid_in;
//valid_out
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
valid_out <= 0;
end
else if(end_cnt) begin
valid_out <= 1;
end
else begin
valid_out <= 0;
end
end
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module of a 16-bit full adder in combinational logic.
Module name:
adder_16bit
Input ports:
a[15:0]: 16-bit input operand A.
b[15:0]: 16-bit input operand B.
Cin: Carry-in input.
Output ports:
y[15:0]: 16-bit output representing the sum of A and B.
Co: Carry-out output.
Implementation:
In the adder_16bit module, you need to design a small bit-width adder(8-bit adder), which will be instantiated multiple times.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = adder_16bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module adder_16bit (
input wire [15:0] a,
input wire [15:0] b,
input wire Cin,
output wire [15:0] y,
output wire Co
);
\ No newline at end of file
`timescale 1ns/1ps
module add16_tb();
reg [15:0] a;
reg [15:0] b;
reg Cin;
wire [15:0] y;
wire Co;
wire [16:0] tb_sum;
wire tb_co;
assign tb_sum = a + b;
assign tb_co = tb_sum[16];
integer i;
integer error = 0;
initial begin
for (i = 0; i < 100; i = i + 1) begin
a = {$random};
b = {$random};
Cin = 0;
#10;
error = (y !== tb_sum[15:0] || Co !== tb_co) ? error + 1 : error;
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d / 100 failures===========", error);
end
end
adder_16bit uut (
.a(a),
.b(b),
.Cin(Cin),
.y(y),
.Co(Co)
);
endmodule
\ No newline at end of file
module verified_adder_16bit (
input wire [15:0] a,
input wire [15:0] b,
input wire Cin,
output wire [15:0] y,
output wire Co
);
wire Co_temp;
add8 add8_inst1 (
.a(a[15:8]),
.b(b[15:8]),
.Cin(Co_temp),
.y(y[15:8]),
.Co(Co)
);
add8 add8_inst2 (
.a(a[7:0]),
.b(b[7:0]),
.Cin(Cin),
.y(y[7:0]),
.Co(Co_temp)
);
endmodule
module add8 (
input wire [7:0] a,
input wire [7:0] b,
input wire Cin,
output wire [7:0] y,
output wire Co
);
wire Co_temp;
add4 add4_inst1 (
.a(a[7:4]),
.b(b[7:4]),
.Cin(Co_temp),
.y(y[7:4]),
.Co(Co)
);
add4 add4_inst2 (
.a(a[3:0]),
.b(b[3:0]),
.Cin(Cin),
.y(y[3:0]),
.Co(Co_temp)
);
endmodule
module add4 (
input wire [3:0] a,
input wire [3:0] b,
input wire Cin,
output wire [3:0] y,
output wire Co
);
wire Co_temp;
add2 add2_inst1 (
.a(a[3:2]),
.b(b[3:2]),
.Cin(Co_temp),
.y(y[3:2]),
.Co(Co)
);
add2 add2_inst2 (
.a(a[1:0]),
.b(b[1:0]),
.Cin(Cin),
.y(y[1:0]),
.Co(Co_temp)
);
endmodule
module add2 (
input wire [1:0] a,
input wire [1:0] b,
input wire Cin,
output wire [1:0] y,
output wire Co
);
wire Co_temp;
add1 add1_inst1 (
.a(a[1]),
.b(b[1]),
.Cin(Co_temp),
.y(y[1]),
.Co(Co)
);
add1 add1_inst2 (
.a(a[0]),
.b(b[0]),
.Cin(Cin),
.y(y[0]),
.Co(Co_temp)
);
endmodule
module add1 (
input wire a,
input wire b,
input wire Cin,
output wire y,
output wire Co
);
assign y = ((~a) & (~b) & Cin | (~a) & b & (~Cin) | a & (~b) & (~Cin) | (a & b & Cin));
assign Co = ((~a & b & Cin) | (a & ~b & Cin) | (a & b & ~Cin) | (a & b & Cin));
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module of a carry-lookahead 32-bit adder that uses the Carry-Lookahead Adder (CLA) architecture.
Module name:
adder_32bit
Input ports:
A[32:1]: 32-bit input operand A.
B[32:1]: 32-bit input operand B.
Output ports:
S[32:1]: 32-bit output representing the sum of A and B.
C32: Carry-out output.
Implementation:
The top module adder_32bit consists of several instances of the 16 bit CLA block you design.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = adder_32bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module adder32_tb;
reg [31:0] A;
reg [31:0] B;
wire [31:0] S;
wire C32;
integer i;
integer error = 0;
reg [33:0] expected_sum;
// Instantiate the module
adder_32bit uut (
.A(A),
.B(B),
.S(S),
.C32(C32)
);
// Randomize inputs and check output
initial begin
for (i = 0; i < 100; i = i + 1) begin
A = $random;
B = $random;
#10;
// Calculate expected sum and carry out
expected_sum = A + B;
error = (S !== expected_sum[31:0] || C32 !== expected_sum[32]) ? error+1 : error;
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d /100 failures===========", error);
end
end
endmodule
\ No newline at end of file
module verified_adder_32bit(A,B,S,C32);
input [32:1] A;
input [32:1] B;
output [32:1] S;
output C32;
wire px1,gx1,px2,gx2;
wire c16;
CLA_16 CLA1(
.A(A[16:1]),
.B(B[16:1]),
.c0(0),
.S(S[16:1]),
.px(px1),
.gx(gx1)
);
CLA_16 CLA2(
.A(A[32:17]),
.B(B[32:17]),
.c0(c16),
.S(S[32:17]),
.px(px2),
.gx(gx2)
);
assign c16 = gx1 ^ (px1 && 0), //c0 = 0
C32 = gx2 ^ (px2 && c16);
endmodule
module CLA_16(A,B,c0,S,px,gx);
input [16:1] A;
input [16:1] B;
input c0;
output gx,px;
output [16:1] S;
wire c4,c8,c12;
wire Pm1,Gm1,Pm2,Gm2,Pm3,Gm3,Pm4,Gm4;
adder_4 adder1(
.x(A[4:1]),
.y(B[4:1]),
.c0(c0),
.c4(),
.F(S[4:1]),
.Gm(Gm1),
.Pm(Pm1)
);
adder_4 adder2(
.x(A[8:5]),
.y(B[8:5]),
.c0(c4),
.c4(),
.F(S[8:5]),
.Gm(Gm2),
.Pm(Pm2)
);
adder_4 adder3(
.x(A[12:9]),
.y(B[12:9]),
.c0(c8),
.c4(),
.F(S[12:9]),
.Gm(Gm3),
.Pm(Pm3)
);
adder_4 adder4(
.x(A[16:13]),
.y(B[16:13]),
.c0(c12),
.c4(),
.F(S[16:13]),
.Gm(Gm4),
.Pm(Pm4)
);
assign c4 = Gm1 ^ (Pm1 & c0),
c8 = Gm2 ^ (Pm2 & Gm1) ^ (Pm2 & Pm1 & c0),
c12 = Gm3 ^ (Pm3 & Gm2) ^ (Pm3 & Pm2 & Gm1) ^ (Pm3 & Pm2 & Pm1 & c0);
assign px = Pm1 & Pm2 & Pm3 & Pm4,
gx = Gm4 ^ (Pm4 & Gm3) ^ (Pm4 & Pm3 & Gm2) ^ (Pm4 & Pm3 & Pm2 & Gm1);
endmodule
module adder_4(x,y,c0,c4,F,Gm,Pm);
input [4:1] x;
input [4:1] y;
input c0;
output c4,Gm,Pm;
output [4:1] F;
wire p1,p2,p3,p4,g1,g2,g3,g4;
wire c1,c2,c3;
adder adder1(
.X(x[1]),
.Y(y[1]),
.Cin(c0),
.F(F[1]),
.Cout()
);
adder adder2(
.X(x[2]),
.Y(y[2]),
.Cin(c1),
.F(F[2]),
.Cout()
);
adder adder3(
.X(x[3]),
.Y(y[3]),
.Cin(c2),
.F(F[3]),
.Cout()
);
adder adder4(
.X(x[4]),
.Y(y[4]),
.Cin(c3),
.F(F[4]),
.Cout()
);
CLA CLA(
.c0(c0),
.c1(c1),
.c2(c2),
.c3(c3),
.c4(c4),
.p1(p1),
.p2(p2),
.p3(p3),
.p4(p4),
.g1(g1),
.g2(g2),
.g3(g3),
.g4(g4)
);
assign p1 = x[1] ^ y[1],
p2 = x[2] ^ y[2],
p3 = x[3] ^ y[3],
p4 = x[4] ^ y[4];
assign g1 = x[1] & y[1],
g2 = x[2] & y[2],
g3 = x[3] & y[3],
g4 = x[4] & y[4];
assign Pm = p1 & p2 & p3 & p4,
Gm = g4 ^ (p4 & g3) ^ (p4 & p3 & g2) ^ (p4 & p3 & p2 & g1);
endmodule
module CLA(c0,c1,c2,c3,c4,p1,p2,p3,p4,g1,g2,g3,g4);
input c0,g1,g2,g3,g4,p1,p2,p3,p4;
output c1,c2,c3,c4;
assign c1 = g1 ^ (p1 & c0),
c2 = g2 ^ (p2 & g1) ^ (p2 & p1 & c0),
c3 = g3 ^ (p3 & g2) ^ (p3 & p2 & g1) ^ (p3 & p2 & p1 & c0),
c4 = g4^(p4&g3)^(p4&p3&g2)^(p4&p3&p2&g1)^(p4&p3&p2&p1&c0);
endmodule
module adder(X,Y,Cin,F,Cout);
input X,Y,Cin;
output F,Cout;
assign F = X ^ Y ^ Cin;
assign Cout = (X ^ Y) & Cin | X & Y;
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module of an 8-bit adder with multiple bit-level adders in combinational logic.
Module name:
adder_8bit
Input ports:
a[7:0]: 8-bit input operand A.
b[7:0]: 8-bit input operand B.
cin: Carry-in input.
Output ports:
sum[7:0]: 8-bit output representing the sum of A and B.
cout: Carry-out output.
Implementation:
The module utilizes a series of bit-level adders (full adders) to perform the addition operation.
Give me the complete code.
\ No newline at end of file
.PHONY: vcs sim clean
TEST_DESIGN = adder_8bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module adder_8bit(
input [7:0] a, b,
input cin,
output [7:0] sum,
output cout);
\ No newline at end of file
`timescale 1ns / 1ps
module testbench;
reg [7:0] a;
reg [7:0] b;
reg cin;
wire [7:0] sum;
wire cout;
integer i; // Declare the loop variable here
integer fail_count;
integer error = 0;
// Instantiate the module
adder_8bit uut (
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
// Randomize inputs and check output
initial begin
for (i = 0; i < 100; i = i + 1) begin
a = $random & 8'hff;
b = $random & 8'hff;
cin = $random & 1'b1;
#10;
error = (sum !== a + b + cin) ? error+1 : error;
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d /100 failures===========", error);
end
end
endmodule
\ No newline at end of file
module verified_adder_8bit(
input [7:0] a, b,
input cin,
output [7:0] sum,
output cout);
wire [8:0] c;
full_adder FA0 (.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c[0]));
full_adder FA1 (.a(a[1]), .b(b[1]), .cin(c[0]), .sum(sum[1]), .cout(c[1]));
full_adder FA2 (.a(a[2]), .b(b[2]), .cin(c[1]), .sum(sum[2]), .cout(c[2]));
full_adder FA3 (.a(a[3]), .b(b[3]), .cin(c[2]), .sum(sum[3]), .cout(c[3]));
full_adder FA4 (.a(a[4]), .b(b[4]), .cin(c[3]), .sum(sum[4]), .cout(c[4]));
full_adder FA5 (.a(a[5]), .b(b[5]), .cin(c[4]), .sum(sum[5]), .cout(c[5]));
full_adder FA6 (.a(a[6]), .b(b[6]), .cin(c[5]), .sum(sum[6]), .cout(c[6]));
full_adder FA7 (.a(a[7]), .b(b[7]), .cin(c[6]), .sum(sum[7]), .cout(c[7]));
assign cout = c[7];
endmodule
module full_adder (input a, b, cin, output sum, cout);
assign {cout, sum} = a + b + cin;
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module of a 64-bit ripple carry adder, which includes several registers to enable the pipeline stages. The output result is available on the result port, and the o_en = 1 indicates the availability of the result.
Module name:
adder_pipe_64bit
Input ports:
clk: Clock input
rst_n: Active low reset signal
i_en: Enable signal for addition operation
adda: 64-bit input operand A
addb: 64-bit input operand B
Output ports:
result: 65-bit output representing the sum of adda and addb.
o_en: Output enable signal.
Implementation:
The module includes several registers to enable the pipeline stages and synchronize the input enable signal (i_en). These registers are controlled by the clock (clk) and reset (rst_n) signals.
The sum values for each pipeline stage are calculated by adding the corresponding input operands and carry signals.
The output enable signal (o_en) is updated based on the pipeline stages and synchronized with the clock (clk) and reset (rst_n) signals.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = adder_pip_64bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module adder_pipe_64bit
#(
parameter DATA_WIDTH = 64,
parameter STG_WIDTH = 16
)
(
input clk,
input rst_n,
input i_en,
input [DATA_WIDTH-1:0] adda,
input [DATA_WIDTH-1:0] addb,
output [DATA_WIDTH:0] result,
output reg o_en
);
module tb_adder64();
parameter DATA_WIDTH = 64;
parameter STG_WIDTH = 16;
reg CLK;
reg RST;
reg i_en;
wire o_en;
reg [DATA_WIDTH-1:0] PLUS_A;
reg [DATA_WIDTH-1:0] PLUS_B;
wire [DATA_WIDTH:0] SUM_OUT;
wire [DATA_WIDTH:0] sum_out_golden;
reg [DATA_WIDTH:0] sum_out_golden_ff1;
reg [DATA_WIDTH:0] sum_out_golden_ff2;
reg [DATA_WIDTH:0] sum_out_golden_ff3;
reg [DATA_WIDTH:0] sum_out_golden_ff4;
assign {sum_out_golden} = PLUS_A + PLUS_B;
always #2 CLK = ~CLK;
integer error = 0;
initial begin
CLK = 0;
repeat (100) begin
RST = 0;
i_en = 0;
#8 RST = 1;
i_en = 1'b1;
PLUS_A = $random * $random;
PLUS_B = $random * $random;
while(o_en==0) begin
@(negedge CLK);
end
error = ((PLUS_A + PLUS_B) == SUM_OUT && o_en ==1 ) ? error : error + 1;
@(negedge CLK);
end
if (error == 0) begin
$display("=========== Your Design Passed ===========");
end
else begin
$display("=========== Test completed with %d / 100 failures ===========", error);
end
$finish;
end
always @(posedge CLK, negedge RST) begin
if (!RST) begin
sum_out_golden_ff1 <= 'd0;
sum_out_golden_ff2 <= 'd0;
sum_out_golden_ff3 <= 'd0;
sum_out_golden_ff4 <= 'd0;
end
else begin
sum_out_golden_ff1 <= sum_out_golden;
sum_out_golden_ff2 <= sum_out_golden_ff1;
sum_out_golden_ff3 <= sum_out_golden_ff2;
sum_out_golden_ff4 <= sum_out_golden_ff3;
end
end
adder_pipe_64bit #(
.DATA_WIDTH(DATA_WIDTH),
.STG_WIDTH(STG_WIDTH)
)
u_pip_add64 (
.clk (CLK),
.rst_n (RST),
.i_en (i_en),
.adda (PLUS_A),
.addb (PLUS_B),
.result (SUM_OUT),
.o_en (o_en)
);
endmodule
\ No newline at end of file
module verified_adder_64bit
#(
parameter DATA_WIDTH = 64,
parameter STG_WIDTH = 16
)
(
input clk,
input rst_n,
input i_en,
input [DATA_WIDTH-1:0] adda,
input [DATA_WIDTH-1:0] addb,
output [DATA_WIDTH:0] result,
output reg o_en
);
reg stage1;
reg stage2;
reg stage3;
wire [STG_WIDTH-1:0] a1;
wire [STG_WIDTH-1:0] b1;
wire [STG_WIDTH-1:0] a2;
wire [STG_WIDTH-1:0] b2;
wire [STG_WIDTH-1:0] a3;
wire [STG_WIDTH-1:0] b3;
wire [STG_WIDTH-1:0] a4;
wire [STG_WIDTH-1:0] b4;
reg [STG_WIDTH-1:0] a2_ff1;
reg [STG_WIDTH-1:0] b2_ff1;
reg [STG_WIDTH-1:0] a3_ff1;
reg [STG_WIDTH-1:0] b3_ff1;
reg [STG_WIDTH-1:0] a3_ff2;
reg [STG_WIDTH-1:0] b3_ff2;
reg [STG_WIDTH-1:0] a4_ff1;
reg [STG_WIDTH-1:0] b4_ff1;
reg [STG_WIDTH-1:0] a4_ff2;
reg [STG_WIDTH-1:0] b4_ff2;
reg [STG_WIDTH-1:0] a4_ff3;
reg [STG_WIDTH-1:0] b4_ff3;
reg c1;
reg c2;
reg c3;
reg c4;
reg [STG_WIDTH-1:0] s1;
reg [STG_WIDTH-1:0] s2;
reg [STG_WIDTH-1:0] s3;
reg [STG_WIDTH-1:0] s4;
reg [STG_WIDTH-1:0] s1_ff1;
reg [STG_WIDTH-1:0] s1_ff2;
reg [STG_WIDTH-1:0] s1_ff3;
reg [STG_WIDTH-1:0] s2_ff1;
reg [STG_WIDTH-1:0] s2_ff2;
reg [STG_WIDTH-1:0] s3_ff1;
assign a1 = adda[STG_WIDTH-1:0];
assign b1 = addb[STG_WIDTH-1:0];
assign a2 = adda[STG_WIDTH*2-1:16];
assign b2 = addb[STG_WIDTH*2-1:16];
assign a3 = adda[STG_WIDTH*3-1:32];
assign b3 = addb[STG_WIDTH*3-1:32];
assign a4 = adda[STG_WIDTH*4-1:48];
assign b4 = addb[STG_WIDTH*4-1:48];
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
stage1 <= 1'b0;
stage2 <= 1'b0;
stage3 <= 1'b0;
o_en <= 1'b0;
end
else begin
stage1 <= i_en;
stage2 <= stage1;
stage3 <= stage2;
o_en <= stage3;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
a2_ff1 <= 'd0;
b2_ff1 <= 'd0;
a3_ff1 <= 'd0;
b3_ff1 <= 'd0;
a3_ff2 <= 'd0;
b3_ff2 <= 'd0;
a4_ff1 <= 'd0;
b4_ff1 <= 'd0;
a4_ff2 <= 'd0;
b4_ff2 <= 'd0;
a4_ff3 <= 'd0;
b4_ff3 <= 'd0;
end
else begin
a2_ff1 <= a2;
b2_ff1 <= b2;
a3_ff1 <= a3;
b3_ff1 <= b3;
a3_ff2 <= a3_ff1;
b3_ff2 <= b3_ff1;
a4_ff1 <= a4;
b4_ff1 <= b4;
a4_ff2 <= a4_ff1;
b4_ff2<= b4_ff1;
a4_ff3 <= a4_ff2;
b4_ff3 <= b4_ff2;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
s1_ff1 <= 'd0;
s1_ff2 <= 'd0;
s1_ff3 <= 'd0;
s2_ff1 <= 'd0;
s2_ff2 <= 'd0;
s3_ff1 <= 'd0;
end
else begin
s1_ff1 <= s1;
s1_ff2 <= s1_ff1;
s1_ff3 <= s1_ff2;
s2_ff1 <= s2;
s2_ff2 <= s2_ff1;
s3_ff1 <= s3;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
c1 <= 1'b0;
s1 <= 'd0;
end
else if (i_en) begin
{c1, s1} <= a1 + b1;
end
else begin
c1 <= c1;
s1 <= s1;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
c2 <= 1'b0;
s2 <= 'd0;
end
else if (stage1) begin
{c2, s2} <= a2_ff1 + b2_ff1 + c1;
end
else begin
c2 <= c2;
s2 <= s2;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
c3 <= 1'b0;
s3 <= 'd0;
end
else if (stage2) begin
{c3, s3} <= a3_ff2 + b3_ff2 + c2;
end
else begin
c3 <= c3;
s3 <= s3;
end
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
c4 <= 1'b0;
s4 <= 'd0;
end
else if (stage3) begin
{c4, s4} <= a4_ff3 + b4_ff3 + c3;
end
else begin
c4 <= c4;
s4 <= s4;
end
end
assign result = {c4, s4, s3_ff1, s2_ff2, s1_ff3};
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement an ALU for a 32-bit MIPS-ISA CPU. The “a” and “b” are the two operands of the ALU, the “aluc” is the opcode, and the “r” gives out the result. “zero” means if the result is zero, “carry” means if there is a carry bit, “negative” means if the result is negative, “overflow” means if the computation is overflow, the “flag” is the result of “slt” and “sltu” instructions. The supported operations and corresponding opcode are shown below:
parameter ADD = 6'b100000;
parameter ADDU = 6'b100001;
parameter SUB = 6'b100010;
parameter SUBU = 6'b100011;
parameter AND = 6'b100100;
parameter OR = 6'b100101;
parameter XOR = 6'b100110;
parameter NOR = 6'b100111;
parameter SLT = 6'b101010;
parameter SLTU = 6'b101011;
parameter SLL = 6'b000000;
parameter SRL = 6'b000010;
parameter SRA = 6'b000011;
parameter SLLV = 6'b000100;
parameter SRLV = 6'b000110;
parameter SRAV = 6'b000111;
parameter LUI = 6'b001111;
Module name:
alu
Input ports:
a: a 32-bit input operand
b: a 32-bit input operand
aluc: a 6-bit control signal for selecting the operation to be performed
Output ports:
r: a 32-bit output representing the result of the operation
zero: a 1-bit output indicating whether the result is zero
carry: a 1-bit output indicating whether a carry occurred during the operation
negative: a 1-bit output indicating whether the result is negative
overflow: a 1-bit output indicating whether an overflow occurred during the operation
flag: a 1-bit output representing a general flag, which is set based on specific operations (SLT and SLTU)
Implementation:
The module uses parameters to define the control signals for various operations, such as ADD, SUB, AND, OR, etc.
The module assigns the input operands to the signed wires and the output result (r) to the lower 32 bits of the register (res[31:0]). The flag output is determined based on the control signal (aluc) and is set to '1' when the operation is SLT or SLTU, and 'z' (high-impedance) otherwise. The zero output is set to '1' when the result is all zeros, and '0' otherwise.
Inside the always block, a case statement is used to perform the appropriate operation based on the control signal (aluc). The result is assigned to the register (res) accordingly. For shift operations (SLL, SRL, SRA, SLLV, SRLV, SRAV), the shift amount is determined by the value of 'a' or 'a[4:0]'. For the LUI operation, the upper 16 bits of 'a' are concatenated with 16 zeros to form the result.
If the control signal (aluc) does not match any defined operation, the result is assigned as 'z' (high-impedance).
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = alu
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns / 1ps
module alu(
input [31:0] a,
input [31:0] b,
input [5:0] aluc,
output [31:0] r,
output zero,
output carry,
output negative,
output overflow,
output flag
);
\ No newline at end of file
0000003d
0000003d
fffffffb
fffffffb
00000000
0000003d
0000003d
ffffffc2
00000001
00000001
10000000
00000000
00000000
10000000
00000000
00000000
001c0000
`timescale 1ns / 1ps
module test_alu();
reg [31:0] a;
reg [31:0] b;
reg [5:0] aluc;
wire [31:0] r;
wire zero;
wire carry;
wire negative;
wire overflow;
wire flag;
reg[4:0]cnt;
alu uut(a,b,aluc,r,zero,carry,negative,overflow,flag);
parameter ADD = 6'b100000;
parameter ADDU = 6'b100001;
parameter SUB = 6'b100010;
parameter SUBU = 6'b100011;
parameter AND = 6'b100100;
parameter OR = 6'b100101;
parameter XOR = 6'b100110;
parameter NOR = 6'b100111;
parameter SLT = 6'b101010;
parameter SLTU = 6'b101011;
parameter SLL = 6'b000000;
parameter SRL = 6'b000010;
parameter SRA = 6'b000011;
parameter SLLV = 6'b000100;
parameter SRLV = 6'b000110;
parameter SRAV = 6'b000111;
parameter JR = 6'b001000;
parameter LUI = 6'b001111;
reg[5:0]opcodes[0:31];
reg[31:0]reference[0:31];
reg error=0;
integer file_open;
initial begin
$readmemh("reference.dat",reference);
opcodes[0]=ADD;
opcodes[1]=ADDU;
opcodes[2]=SUB;
opcodes[3]=SUBU;
opcodes[4]=AND;
opcodes[5]=OR;
opcodes[6]=XOR;
opcodes[7]=NOR;
opcodes[8]=SLT;
opcodes[9]=SLTU;
opcodes[10]=SLL;
opcodes[11]=SRL;
opcodes[12]=SRA;
opcodes[13]=SLLV;
opcodes[14]=SRLV;
opcodes[15]=SRAV;
//opcodes[16]=JR;
opcodes[16]=LUI;
a=32'h0000001c;
b=32'h00000021;
#5;
cnt = 0;
for(cnt=0;cnt<17;cnt=cnt+1)
begin
#5;
aluc=opcodes[cnt];
#5;
error=error|(reference[cnt]!=r);
end
if(error==0)
begin
$display("===========Your Design Passed===========");
end
else
begin
$display("===========Error===========");
end
$finish;
end
endmodule
`timescale 1ns / 1ps
module verified_alu(
input [31:0] a,
input [31:0] b,
input [5:0] aluc,
output [31:0] r,
output zero,
output carry,
output negative,
output overflow,
output flag
);
parameter ADD = 6'b100000;
parameter ADDU = 6'b100001;
parameter SUB = 6'b100010;
parameter SUBU = 6'b100011;
parameter AND = 6'b100100;
parameter OR = 6'b100101;
parameter XOR = 6'b100110;
parameter NOR = 6'b100111;
parameter SLT = 6'b101010;
parameter SLTU = 6'b101011;
parameter SLL = 6'b000000;
parameter SRL = 6'b000010;
parameter SRA = 6'b000011;
parameter SLLV = 6'b000100;
parameter SRLV = 6'b000110;
parameter SRAV = 6'b000111;
parameter JR = 6'b001000;
parameter LUI = 6'b001111;
wire signed [31:0] a_signed;
wire signed [31:0] b_signed;
reg [32:0] res;
assign a_signed = a;
assign b_signed = b;
assign r = res[31:0];
assign flag = (aluc == SLT || aluc == SLTU) ? ((aluc == SLT) ? (a_signed < b_signed) : (a < b)) : 1'bz;
assign zero = (res == 32'b0) ? 1'b1 : 1'b0;
always @ (a or b or aluc)
begin
case(aluc)
ADD: begin
res <= a_signed + b_signed;
end
ADDU: begin
res <= a + b;
end
SUB: begin
res <= a_signed - b_signed;
end
SUBU: begin
res <= a - b;
end
AND: begin
res <= a & b;
end
OR: begin
res <= a | b;
end
XOR: begin
res <= a ^ b;
end
NOR: begin
res <= ~(a | b);
end
SLT: begin
res <= a_signed < b_signed ? 1 : 0;
end
SLTU: begin
res <= a < b ? 1 : 0;
end
SLL: begin
res <= b << a;
end
SRL: begin
res <= b >> a;
end
SRA: begin
res <= b_signed >>> a_signed;
end
SLLV: begin
res <= b << a[4:0];
end
SRLV: begin
res <= b >> a[4:0];
end
SRAV: begin
res <= b_signed >>> a_signed[4:0];
end
LUI: begin
res <= {a[15:0], 16'h0000};
end
default:
begin
res <= 32'bz;
end
endcase
end
endmodule
Please act as a professional verilog designer.
Implement an asynchronous FIFO, FIFO bit width and depth can be configured(parameter DEPTH = 16, parameter WIDTH = 8). The asynchronous FIFO structure is divided into several parts. The first part is dual-port RAM, which is used for data storage. Instantiate dual-port RAM as a submodule, The RAM ports are input wclk, input wenc, input [$clog2(DEPTH)-1:0] waddr, input [WIDTH-1:0] wdata, input rclk, input renc, input [$clog2(DEPTH)-1:0] raddr, output reg [WIDTH-1:0] rdata. The second part is the data write controller. The third part is the data read controller. The fourth part is the read pointer synchronizer. The read pointer is collected using the two-stage trigger of the write clock and output to the data write controller. The fifth part is the write pointer synchronizer, which uses the two-stage trigger of the read clock to collect the write pointer and output it to the data read controller.
The method of empty and full judgment is to generate empty and full signals by comparing the Gray code. Use 4-bit Gray code as a read/write pointer for a FIFO with depth 8. The gray code is converted to a four-digit binary number, using the lower three digits of the binary number as the address to access RAM. When the read and write Pointers are equal, the FIFO is null.
When the write pointer has one more cycle RAM than the read pointer, the highest and second-highest bits of the read and write pointer are opposite, the remaining bits are the same, and the FIFO is full.
Module name:
asyn_fifo
Input ports:
wclk: Write clock signal used for synchronous write operations.
rclk: Read clock signal used for synchronous read operations.
wrstn: Write reset signal. Defined as 0 for reset and 1 for reset signal inactive.
rrstn: Read reset signal. Defined as 0 for reset and 1 for reset signal inactive.
winc: Write increment signal. Used to trigger write operations.
rinc: Read increment signal. Used to trigger read operations.
wdata: Write data input. The width [WIDTH-1:0] is configurable and represents the data to be written into the FIFO.
Output ports:
wfull: Write full signal. Indicates if the FIFO is full and cannot accept further write operations.
rempty: Read empty signal. Indicates if the FIFO is empty and cannot provide any data for read operations.
rdata: Read data output. The width [WIDTH-1:0] is configurable and represents the data read from the FIFO.
Parameter:
WIDTH = 8
DEPTH = 16
Implementation:
The module implements an asynchronous FIFO using a dual-port RAM module and additional logic for managing read and write pointers.
Dual-port RAM:
The module instantiates a dual-port RAM module named "dual_port_RAM" with configurable depth and width.
The RAM module has separate clock inputs for write (wclk) and read (rclk) operations.
The RAM module has separate address inputs for write (waddr) and read (raddr) operations.
The RAM module has a write enable input (wenc) and a write data input (wdata).
The RAM module has a read enable input (renc) and a read data output (rdata).
The RAM module stores data in a two-dimensional array, RAM_MEM, with a size of DEPTH by WIDTH.
Write and Read Pointers:
The module includes logic to manage write and read pointers for asynchronous operation.
The write and read pointers are represented by binary registers, waddr_bin and raddr_bin, respectively.
The write and read pointers are incremented based on the write and read increment signals (winc and rinc), respectively.
The write pointer is incremented on the positive edge of the write clock (posedge wclk) and reset to 0 on write reset (~wrstn).
The read pointer is incremented on the positive edge of the read clock (posedge rclk) and reset to 0 on read reset (~rrstn).
Gray Code Conversion:
The write and read pointers are converted to Gray code using XOR operations with right-shifted values.
The converted write and read pointers are stored in registers wptr and rptr, respectively.
The Gray code conversion reduces glitches and ensures proper synchronization of the write and read pointers.
Pointer Buffers:
The module includes buffer registers (wptr_buff and rptr_buff) to hold the previous values of the write and read pointers.
The buffer registers are updated on the positive edge of the respective clocks and reset to 0 on the respective resets (~wrstn and ~rrstn).
The buffer registers are used to synchronize the write and read pointers for determining the full and empty conditions.
Full and Empty Signals:
The module compares the current write and read pointers (wptr and rptr_syn) to determine if the FIFO is full or empty.
The wfull output is set to 1 when the write pointer is equal to the bitwise negation of the most significant bit of the read pointer concatenated with the remaining bits of the read pointer.
The rempty output is set to 1 when the read pointer is equal to the write pointer.
Input and Output Connections:
The module connects the input and output signals to the dual-port RAM module based on the control signals and pointer values.
The wen and ren signals control the write and read enable signals of the RAM module, respectively.
The wdata input is connected to the write data input (wdata) of the RAM module.
The rdata output is connected to the read data output (rdata) of the RAM module.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = asyn_fifo
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
/***************************************RAM*****************************************/
module dual_port_RAM #(parameter DEPTH = 16, parameter WIDTH = 8)
(
input wclk ,
input wenc ,
input [$clog2(DEPTH)-1:0] waddr ,
input [WIDTH-1:0] wdata ,
input rclk ,
input renc ,
input [$clog2(DEPTH)-1:0] raddr ,
output reg [WIDTH-1:0] rdata
);
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
always @(posedge wclk) begin
if(wenc)
RAM_MEM[waddr] <= wdata;
end
always @(posedge rclk) begin
if(renc)
rdata <= RAM_MEM[raddr];
end
endmodule
/**************************************AFIFO*****************************************/
module asyn_fifo#(
parameter WIDTH = 8,
parameter DEPTH = 16
)(
input wclk ,
input rclk ,
input wrstn ,
input rrstn ,
input winc ,
input rinc ,
input [WIDTH-1:0] wdata ,
output wire wfull ,
output wire rempty ,
output wire [WIDTH-1:0] rdata
);
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
01
01
ab
ab
ac
ac
ad
ad
ae
ae
af
af
b0
b0
b1
b1
b2
b2
b3
b3
b4
b4
b5
b5
b6
b6
b7
b7
b8
b8
b9
b9
01
01
01
01
ab
ab
ac
ac
ad
ad
ae
ae
af
af
b0
b0
`timescale 1ns/1ns
module asyn_fifo_tb;
reg wclk, rclk, wrstn, rrstn, winc, rinc;
reg [7:0] wdata;
wire wfull, rempty;
wire [7:0] rdata;
asyn_fifo #(.WIDTH(8), .DEPTH(16)) dut (
.wclk(wclk),
.rclk(rclk),
.wrstn(wrstn),
.rrstn(rrstn),
.winc(winc),
.rinc(rinc),
.wdata(wdata),
.wfull(wfull),
.rempty(rempty),
.rdata(rdata)
);
always #5 wclk = ~wclk;
always #10 rclk = ~rclk;
initial begin
wclk = 0;
rclk = 0;
wrstn = 0;
rrstn = 0;
winc = 0;
rinc = 0;
wdata = 0;
end
// Apply reset and initialize FIFO
initial begin
wrstn = 0;
rrstn = 0;
#20;
wrstn = 1;
rrstn = 1;
#10;
winc = 1; // Enable write
wdata = 8'hAA; // Write data
#10;
winc = 0; // Disable write
#500;
rinc = 1;
#500;
#10;
$finish;
end
integer outfile1;
integer outfile2;
integer outfile3;
reg[31:0]data1[0:50];
reg[31:0]data2[0:50];
reg[31:0]data3[0:50];
integer i = 0;
integer error =0;
initial begin
#550;
$readmemh("wfull.txt",data1);
$readmemh("rempty.txt",data2);
$readmemh("tdata.txt",data3);
// outfile1 = $fopen("wfull.txt", "w");
// outfile2 = $fopen("rempty.txt", "w");
// outfile3 = $fopen("tdata.txt", "w");
repeat(48) begin
#10;
// $fwrite(outfile1, "%h\n", wfull);
// $fwrite(outfile2, "%h\n", rempty);
// $fwrite(outfile3, "%h\n", rdata);
error = (wfull==data1[i] && rempty == data2[i] && rdata ==data3[i]) ? error:error+1;
i = i + 1;
end
if(error==0)
begin
$display("===========Your Design Passed===========");
end
else
begin
$display("===========Error===========");
end
// $fclose(outfile1);
// $fclose(outfile2);
// $fclose(outfile3);
end
// Display FIFO status
// always @(posedge wclk) begin
// $display("wfull=%d, rempty=%d, rdata=%h", wfull, rempty, rdata);
// end
initial begin
repeat (17) begin
#20;
if (wfull) begin
// $display("FIFO is full (wfull=1) at depth %d", $time);
break;
end
winc = 1; // Enable write
wdata = wdata + 1; // Write data
#10;
winc = 0; // Disable write
end
end
endmodule
\ No newline at end of file
`timescale 1ns/1ns
/***************************************RAM*****************************************/
module dual_port_RAM #(parameter DEPTH = 16, parameter WIDTH = 8)
(
input wclk ,
input wenc ,
input [$clog2(DEPTH)-1:0] waddr ,
input [WIDTH-1:0] wdata ,
input rclk ,
input renc ,
input [$clog2(DEPTH)-1:0] raddr ,
output reg [WIDTH-1:0] rdata
);
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
always @(posedge wclk) begin
if(wenc)
RAM_MEM[waddr] <= wdata;
end
always @(posedge rclk) begin
if(renc)
rdata <= RAM_MEM[raddr];
end
endmodule
/**************************************AFIFO*****************************************/
module verified_asyn_fifo#(
parameter WIDTH = 8,
parameter DEPTH = 16
)(
input wclk ,
input rclk ,
input wrstn ,
input rrstn ,
input winc ,
input rinc ,
input [WIDTH-1:0] wdata ,
output wire wfull ,
output wire rempty ,
output wire [WIDTH-1:0] rdata
);
parameter ADDR_WIDTH = $clog2(DEPTH);
reg [ADDR_WIDTH:0] waddr_bin;
reg [ADDR_WIDTH:0] raddr_bin;
always @(posedge wclk or negedge wrstn) begin
if(~wrstn) begin
waddr_bin <= 'd0;
end
else if(!wfull && winc)begin
waddr_bin <= waddr_bin + 1'd1;
end
end
always @(posedge rclk or negedge rrstn) begin
if(~rrstn) begin
raddr_bin <= 'd0;
end
else if(!rempty && rinc)begin
raddr_bin <= raddr_bin + 1'd1;
end
end
wire [ADDR_WIDTH:0] waddr_gray;
wire [ADDR_WIDTH:0] raddr_gray;
reg [ADDR_WIDTH:0] wptr;
reg [ADDR_WIDTH:0] rptr;
assign waddr_gray = waddr_bin ^ (waddr_bin>>1);
assign raddr_gray = raddr_bin ^ (raddr_bin>>1);
always @(posedge wclk or negedge wrstn) begin
if(~wrstn) begin
wptr <= 'd0;
end
else begin
wptr <= waddr_gray;
end
end
always @(posedge rclk or negedge rrstn) begin
if(~rrstn) begin
rptr <= 'd0;
end
else begin
rptr <= raddr_gray;
end
end
reg [ADDR_WIDTH:0] wptr_buff;
reg [ADDR_WIDTH:0] wptr_syn;
reg [ADDR_WIDTH:0] rptr_buff;
reg [ADDR_WIDTH:0] rptr_syn;
always @(posedge wclk or negedge wrstn) begin
if(~wrstn) begin
rptr_buff <= 'd0;
rptr_syn <= 'd0;
end
else begin
rptr_buff <= rptr;
rptr_syn <= rptr_buff;
end
end
always @(posedge rclk or negedge rrstn) begin
if(~rrstn) begin
wptr_buff <= 'd0;
wptr_syn <= 'd0;
end
else begin
wptr_buff <= wptr;
wptr_syn <= wptr_buff;
end
end
assign wfull = (wptr == {~rptr_syn[ADDR_WIDTH:ADDR_WIDTH-1],rptr_syn[ADDR_WIDTH-2:0]});
assign rempty = (rptr == wptr_syn);
/***********RAM*********/
wire wen ;
wire ren ;
wire wren;//high write
wire [ADDR_WIDTH-1:0] waddr;
wire [ADDR_WIDTH-1:0] raddr;
assign wen = winc & !wfull;
assign ren = rinc & !rempty;
assign waddr = waddr_bin[ADDR_WIDTH-1:0];
assign raddr = raddr_bin[ADDR_WIDTH-1:0];
dual_port_RAM #(.DEPTH(DEPTH),
.WIDTH(WIDTH)
)dual_port_RAM(
.wclk (wclk),
.wenc (wen),
.waddr(waddr[ADDR_WIDTH-1:0]), //The depth is logarithmic to 2 to get the bit width of the address
.wdata(wdata), //data_write
.rclk (rclk),
.renc (ren),
.raddr(raddr[ADDR_WIDTH-1:0]),
.rdata(rdata)
);
endmodule
\ No newline at end of file
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Please act as a professional verilog designer.
Implement a module of perpetual calendar. The starting value of Secs, Mins, and Hours are all 0. Both Secs and Mins loop continuously from 0 to 59. When Secs=59, Min increases by 1 at the next cycle, and when Min=59 && Secs=59, Hours increases by 1 at the next cycle. Hours is counted from the 0-23 cycle.
Module name:
calendar
Input ports:
CLK: Clock input
RST: Active high reset signal
Output ports:
Hours: 6-bit output representing the current hours
Mins: 6-bit output representing the current minutes
Secs: 6-bit output representing the current seconds
Implementation:
The calendar module uses three always blocks to update the values of seconds, minutes, and hours based on the clock signal and reset signal.
The first always block triggers on the positive edge of the clock signal (posedge CLK) or the positive edge of the reset signal (posedge RST). It checks if the reset signal is active (RST) and sets the seconds value (Secs) to 0. If the seconds value is 59, it wraps around and sets the seconds value to 0. Otherwise, it increments the seconds value by 1.
The second always block also triggers on the positive edge of the clock signal or the positive edge of the reset signal. It handles the minutes value (Mins). If the reset signal is active, it sets the minutes value to 0. If both the minutes and seconds values are 59, it wraps around and sets the minutes value to 0. If the seconds value is 59, it increments the minutes value by 1. Otherwise, it keeps the minutes value unchanged.
The third always block triggers on the positive edge of the clock signal or the positive edge of the reset signal. It handles the hours value (Hours). If the reset signal is active, it sets the hours value to 0. If the hours, minutes, and seconds values are all at their maximum (23, 59, and 59 respectively), it wraps around and sets the hours value to 0. If the minutes and seconds values are both 59, it increments the hours value by 1. Otherwise, it keeps the hours value unchanged.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = calendar
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module calendar(CLK,RST,Hours,Mins,Secs);
`timescale 1ns/1ps
module main();
reg clk,rst;
wire[5:0] out1,out2,out3;
calendar dut(.CLK(clk),.RST(rst),.Hours(out1),.Mins(out2),.Secs(out3));
initial begin
clk=0;
forever #5 clk=~clk;
end
integer outfile;
reg [17:0] clocktime;
always @(posedge clk) begin
clocktime[17:12] <= out1;
clocktime[11:6] <= out2;
clocktime[5:0] <= out3;
end
reg [17:0] reference_data [0:4000];
integer i=0;
integer error = 0;
initial begin
#10;
rst = 1;
#25;
rst = 0;
// outfile = $fopen("reference.txt", "w");
$readmemh("reference.txt",reference_data);
repeat(4000) begin
// $fwrite(outfile, "%h\n", clocktime);
error = (reference_data[i] == clocktime) ? error :error +1;
i = i + 1;
#10;
end
if(error==0)
begin
$display("===========Your Design Passed===========");
end
else
begin
$display("===========Error===========");
end
// $fclose(outfile);
$finish;
end
endmodule
\ No newline at end of file
module verified_calendar(CLK,RST,Hours,Mins,Secs);
input CLK,RST;
output [5:0] Hours,Mins,Secs;
reg [5:0] Hours,Mins,Secs;
always@(posedge CLK or posedge RST) begin
if (RST)
Secs <= 0;
else if (Secs == 59)
Secs <= 0;
else
Secs <= Secs + 1;
end
always@(posedge CLK or posedge RST) begin
if (RST)
Mins <= 0;
else if((Mins==59)&&(Secs==59))
Mins <= 0;
else if(Secs== 59)
Mins <= Mins + 1;
else
Mins <= Mins;
end
always@(posedge CLK or posedge RST) begin
if (RST)
Hours <= 0;
else if((Hours == 23)&&(Mins==59)&&(Secs==59))
Hours <= 0;
else if((Mins == 59)&&(Secs==59))
Hours <= Hours + 1;
else
Hours <= Hours;
end
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module of a counter design that requires counting from 4 'b0000 to 4' d11. The counting can be controlled by the input signal valid_count. That is, the count is paused if valid_count is 0. The counter increments on each clock cycle when the valid_count signal is active and resets to 0 when the reset signal (rst_n) is active.
Module name:
counter_12
Input ports:
rst_n: Reset signal (active low)
clk: Clock signal
valid_count: Signal to enable counting
Output ports:
out: 4-bit output representing the current count value
Implementation:
If the reset signal is active (!rst_n), the counter is reset to 0 by assigning the value 4'b0000 to the output register (out). If the valid_count signal is 1, the counter increments. It checks if the current count value (out) is equal to 4'd11 (maximum count value). If it is, the counter wraps around and resets to 0 by assigning the value 4'b0000 to the output register (out). Otherwise, it increments the output register by 1. If the valid_count = 0, the counter will stop, and the output register (out) remains unchanged.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = counter_12
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ps
module counter_12
(
input rst_n,
input clk,
input valid_count,
output reg [3:0] out
);
`timescale 1ns/1ps
module counter_12_tb;
reg clk, rst_n, valid_count;
wire [3:0] out;
counter_12 dut (
.rst_n(rst_n),
.clk(clk),
.valid_count(valid_count),
.out(out)
);
always #5 clk = ~clk;
integer i = 0;
integer error = 0;
initial begin
clk = 0;
rst_n = 0;
valid_count = 0;
#20 rst_n = 1;
// testcase1: validation of valid_count
repeat(15) begin
error = (out == 0) ?error:error+1;
#10;
end
// testcase2: counter
#100 valid_count = 1;
repeat(11) begin
error = (out == i) ?error:error+1;
i = i+1;
#10;
end
// testcase3: the count is paused if valid_count is invalid
valid_count = 0;
repeat(5) begin
error = (out == 11) ?error:error+1;
#10;
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Failed===========", error);
end
$finish;
end
endmodule
\ No newline at end of file
`timescale 1ns/1ps
module verified_counter_12
(
input rst_n,
input clk,
input valid_count,
output reg [3:0] out
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
begin
out <= 4'b0000;
end
else if (valid_count)
begin
if (out == 4'd11)
begin
out <= 4'b0000;
end
else begin
out <= out + 1;
end
end
else begin
out <= out; // Pause the count when valid_count is invalid
end
end
endmodule
Please act as a professional verilog designer.
Implement a 16-bit divider module, the dividend is 16-bit and the divider is 8-bit in combinational logic. Extract the higher bits of the dividend, matching the bit width of the divisor. Compare these bits with the divisor: if the dividend bits are greater, set the quotient to 1, otherwise set it to 0, and use the difference as the remainder. Concatenate the remainder with the highest remaining 1-bit of the dividend, and repeat the process until all dividend bits are processed.
Module name:
div_16bit
Input ports:
A: 16-bit dividend.
B: 8-bit divisor.
Output ports:
result: 16-bit quotient.
odd: 16-bit remainder.
Implementation:
The module uses two always blocks to perform the division operation.
The first always block is a combinational block triggered by any change in the input values A and B. It updates the values of two registers, a_reg and b_reg, with the values of A and B, respectively.
The second always block is also a combinational block triggered by any change in the input values A and B.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = div_16bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module div_16bit(
input wire [15:0] A,
input wire [7:0] B,
output wire [15:0] result,
output wire [15:0] odd
);
`timescale 1ns/1ps
module tb_division();
reg [15:0] A;
reg [7:0] B;
wire [15:0] result;
wire [15:0] odd;
integer i;
reg [15:0] expected_result;
integer error = 0;
reg [15:0] expected_result;
reg [15:0] expected_odd;
initial begin
for (i = 0; i < 100; i = i + 1) begin
A = $urandom_range(1'b0, 16'b1111_1111_1111_1111);
B = $urandom_range(1'b1, 8'b1111_1111);
expected_result = A/B;
expected_odd = A%B;
#10;
error = (expected_odd != odd || expected_result != result) ? error+1 : error;
// $display("A = %d, B = %d, Result = %d, odd = %d", A, B, result, odd);
end
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d /100 failures===========", error);
end
$finish;
end
div_16bit uut (.A(A), .B(B), .result(result), .odd(odd));
endmodule
\ No newline at end of file
module verified_div_16bit(
input wire [15:0] A,
input wire [7:0] B,
output wire [15:0] result,
output wire [15:0] odd
);
reg [15:0] a_reg;
reg [15:0] b_reg;
reg [31:0] tmp_a;
reg [31:0] tmp_b;
integer i;
always@(*) begin
a_reg = A;
b_reg = B;
end
always@(*) begin
begin
tmp_a = {16'b0, a_reg};
tmp_b = {b_reg, 16'b0};
for(i = 0;i < 16;i = i+1) begin
tmp_a = tmp_a << 1;
if (tmp_a >= tmp_b) begin
tmp_a = tmp_a - tmp_b + 1;
end
else begin
tmp_a = tmp_a;
end
end
end
end
assign odd = tmp_a[31:16];
assign result = tmp_a[15:0];
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a module for edge detection. There is a slowly changing 1-bit signal a. When "a" changes from 0 to 1, the indicating signal rise is 1. When "a" changes from 1 to 0, the falling edge of signal a is shown, the indicating signal down is 1. rise or down will be set to 1 on the next clock when the corresponding edge appears, and then return to 0 until the corresponding edge appears again.
Module name:
edge_detect
Input ports:
clk: Clock signal.
rst_n: Reset signal (active low).
a: Input signal.
Output ports:
rise: Output signal indicating a rising edge.
down: Output signal indicating a falling edge.
Implementation:
The edge_detect module detects rising and falling edges in the input signal a and generates corresponding output signals rise and down. The rising and falling edges are detected on the positive edge of the clock signal clk. If a rising edge is detected, the rise output signal is set to 1. If a falling edge is detected, the down output signal is set to 1. Otherwise, both output signals are set to 0. These output signals are synchronized with the clock and remain set to 1 until the corresponding edge appears again.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = edge_detect
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
`timescale 1ns/1ns
module testbench;
reg clk;
reg rst_n;
reg a;
wire rise;
wire down;
edge_detect dut (
.clk(clk),
.rst_n(rst_n),
.a(a),
.rise(rise),
.down(down)
);
integer error=0;
initial begin
// Initialize inputs
clk = 0;
rst_n = 1;
a = 0;
// Wait for a few clock cycles to ensure the module stabilizes
#5;
// Test scenario 1: No edge
a = 0;
#10;
a = 0;
#10;
// $display("rise: %b, down: %b", rise, down);
error = (rise != 0 && down != 0) ? error+1 : error;
// Test scenario 2: Rising edge
a = 0;
#10;
a = 1;
#10;
a = 1;
// $display("rise: %b, down: %b", rise, down);
error = (rise != 1 && down != 0) ? error+1 : error;
// Test scenario 3: Falling edge
a = 1;
#10;
a = 0;
#10;
a = 0;
// $display("rise: %b, down: %b", rise, down);
error = (rise != 0 && down != 1) ? error+1 : error;
// Test scenario 4: Reset
rst_n = 0;
#10;
rst_n = 1;
#10;
// $display("rise: %b, down: %b", rise, down);
error = (rise != 0 && down != 0) ? error+1 : error;
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Error===========", error);
end
// Finish simulation
$finish;
end
always #5 clk = ~clk;
endmodule
`timescale 1ns/1ns
module verified_edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg a0;
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
rise <= 1'b0;
down <= 1'b0;
end
else begin
if(a & ~a0) begin
rise <= 1;
down <= 0;
end
else if (~a & a0) begin
rise <= 0;
down <= 1;
end else begin
rise <= 0;
down <= 0;
end
end
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
a0 <= 0;
else
a0 <= a;
end
endmodule
Please act as a professional verilog designer.
Implement a frequency divider that the input clock frequency of 100MHz signal, and the outputs are 3 clock frequencies: 50MHz, 10MHz, 1MHz.
Module name:
freq_div
Input ports:
CLK_in: Input clock signal
RST: Reset signal
Output ports:
CLK_50: Output clock signal with a frequency of CLK_in divided by 2.
CLK_10: Output clock signal with a frequency of CLK_in divided by 10.
CLK_1: Output clock signal with a frequency of CLK_in divided by 100.
Implementation:
The module uses three counters to divide the input clock frequency.
CLK_50 generation:
On every positive edge of CLK_in or RST, if RST is active, CLK_50 is set to 0.
Otherwise, CLK_50 is toggled by inverting its current value.
CLK_10 generation:
On every positive edge of CLK_in or RST, if RST is active, CLK_10 is set to 0, and the counter cnt_10 is reset to 0.
If the counter cnt_10 reaches a value of 4, CLK_10 is toggled by inverting its current value, and the counter cnt_10 is reset to 0.
Otherwise, the counter cnt_10 is incremented by 1.
CLK_1 generation:
On every positive edge of CLK_in or RST, if RST is active, CLK_1 is set to 0, and the counter cnt_100 is reset to 0.
If the counter cnt_100 reaches a value of 49, CLK_1 is toggled by inverting its current value, and the counter cnt_100 is reset to 0.
Otherwise, the counter cnt_100 is incremented by 1.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = freq_div
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module freq_div (CLK_in,CLK_50,CLK_10,CLK_1,RST);
module test ();
reg clk,rst;
wire out1;
wire out2;
wire out3;
freq_div dut(.CLK_in(clk),.RST(rst),.CLK_50(out1),.CLK_10(out2),.CLK_1(out3));
initial begin
clk = 0;
forever #5 clk = ~clk;
end
integer error=0;
initial begin
#10;
rst = 1;
#35;
rst = 0;
// 45, clk: 1, clk50: 0, rclk10: 0, clk1: 0
error = (out1 != 0 || out2 != 0 || out3 !=0 ) ? error+1 : error;
// 55, clk: 1, clk50: 1, rclk10: 0, clk1: 0
#10;
error = (out1 != 1 || out2 != 0 || out3 !=0 ) ? error+1 : error;
// 95, clk50: 0, rclk10: 1, clk1: 0
#40;
error = (out1 != 1 || out2 != 1 || out3 !=0 ) ? error+1 : error;
// 225, clk: 1, clk50: 0, rclk10: 1, clk1: 0
#130;
error = (out1 != 0 || out2 != 1 || out3 !=0 ) ? error+1 : error;
// 625, clk: 1, clk50: 0, rclk10: 1, clk1: 1
#400;
error = (out1 != 0 || out2 != 1 || out3 !=1 ) ? error+1 : error;
// 1035, clk: 1, clk50: 1, rclk10: 1, clk1: 1
#410;
error = (out1 != 1 || out2 != 1 || out3 !=1 ) ? error+1 : error;
if (error == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Error===========", error);
end
$finish;
end
// initial begin
// repeat(500) begin
// #5
// $display("Time: %t, clk: %b, clk50: %b, rclk10: %b, clk1: %b", $time, clk, out1, out2, out3);
// end
// end
endmodule
\ No newline at end of file
module freq_div (CLK_in,CLK_50,CLK_10,CLK_1,RST);
input CLK_in,RST;
output reg CLK_50,CLK_10,CLK_1;
reg [3:0] cnt_10;
reg [6:0] cnt_100;
always @(posedge CLK_in or posedge RST) begin
if (RST) begin
CLK_50<= 1'b0;
end
else begin
CLK_50<= ~CLK_50;
end
end
always @(posedge CLK_in or posedge RST) begin
if (RST) begin
CLK_10<= 1'b0;
cnt_10<=0;
end
else if (cnt_10==4) begin
CLK_10<= ~CLK_10;
cnt_10<=0;
end
else begin
cnt_10<=cnt_10+1;
end
end
always @(posedge CLK_in or posedge RST) begin
if (RST) begin
CLK_1<= 1'b0;
cnt_100<=0;
end
else if (cnt_100==49) begin
CLK_1<= ~CLK_1;
cnt_100<=0;
end
else begin
cnt_100<=cnt_100+1;
end
end
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement a Mealy FSM detection circuit that detects a single-bit input IN. When the input is 10011, output MATCH is 1, and MATCH is 0 in other cases. Support for continuous input and loop detection.
Module name:
fsm
Input ports:
IN: Input signal to the FSM.
CLK: Clock signal used for synchronous operation.
RST: Reset signal to initialize the FSM.
Output ports:
MATCH: Output signal indicating a match condition based on the FSM state.
Implementation:
The module implements an FSM detection.
On every change in the input signal (IN) or positive edge of CLK or RST, if RST is active, the output signal MATCH is set to 0.
If the sequence of inputs IN is 1, 0, 0, 1, 1, the MATCH signal is 1 at the same time as the last occurrence of IN=1. If the sequence of inputs IN is 1, 0, 0, 1, 1, 0, 0, 1, 1, the MATCH signal becomes 1 at the fifth and ninth of IN; otherwise, it is set to 0.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = fsm
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module main();
reg clk,rst;
reg IN;
wire MATCH;
fsm DUT(.CLK(clk),.RST(rst),.IN(IN),.MATCH(MATCH));
initial begin
clk=0;
forever #5 clk=~clk;
end
integer error = 0;
initial begin
#10;
rst =1;
#28;
rst = 0;
IN = 0;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//0
error = (MATCH==0)? error:error+1;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//00
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//001
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//0011
error = (MATCH==0)? error:error+1;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//00110
error = (MATCH==0)? error:error+1;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//001100
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//0011001
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//00110011
error = (MATCH==1)? error:error+1;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//001100110
error = (MATCH==0)? error:error+1;
#10 IN=0;
// $display("%b, %b", MATCH, DUT.ST_cr);//0011001100
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//00110011001
error = (MATCH==0)? error:error+1;
#10 IN=1;
// $display("%b, %b", MATCH, DUT.ST_cr);//001100110011
error = (MATCH==1)? error:error+1;
if(error==0)begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Error===========");
end
$finish;
end
endmodule
\ No newline at end of file
module verified_fsm(IN,MATCH,CLK,RST);
input IN,CLK,RST;
output reg MATCH;
reg [2:0] ST_cr,ST_nt;
parameter s0 = 3'b000;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
always@(posedge CLK or posedge RST) begin
if(RST)
ST_cr <= s0;
else
ST_cr <= ST_nt;
end
always@(*) begin
case(ST_cr)
s0:begin
if (IN==0)
ST_nt = s0;
else
ST_nt = s1;
end
s1:begin
if (IN==0)
ST_nt = s2;
else
ST_nt = s1;
end
s2:begin
if (IN==0)
ST_nt = s3;
else
ST_nt = s1;
end
s3:begin
if (IN==0)
ST_nt = s0;
else
ST_nt = s4;
end
s4:begin
if (IN==0)
ST_nt = s2;
else
ST_nt = s5;
end
s5:begin
if (IN==0)
ST_nt = s2;
else
ST_nt = s1;
end
endcase
end
always@(*) begin
if(RST)
MATCH <= 0;
else if (ST_cr == s4 && IN == 1)
MATCH <= 1;
else
MATCH <= 0;
end
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement the design of an unsigned 16-bit multiplier. It utilizes shift and accumulate operations to generate the product output (yout). The module also includes control signals such as clock (clk), reset (rst_n), and start (start), along with a completion flag (done) indicating the completion of the multiplication operation.
Module name:
multi_16bit
Input ports:
clk: Chip clock signal.
rst_n: Active-low reset signal. Defined as 0 for chip reset and 1 for reset signal inactive.
start: Chip enable signal to initiate the multiplication operation.
ain: Input signal representing the multiplicand (a) with a data width of 16 bits.
bin: Input signal representing the multiplier (b) with a data width of 16 bits.
Output ports:
yout: Product output signal with a data width of 32 bits.
done: Chip output flag signal. Defined as 1 indicates the completion of the multiplication operation.
Implementation:
Data bit control:
On every positive edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the shift count register (i) is updated.
If the reset signal (rst_n) is low, indicating a reset condition, the shift count register (i) is set to 0.
If the start signal is active (start) and the shift count register (i) is less than 17, the shift count register (i) increments by 1.
If the start signal is inactive (!start), the shift count register (i) is reset to 0.
Multiplication completion flag generation:
On every positive edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the multiplication completion flag (done_r) is updated.
If the reset signal (rst_n) is low, the multiplication completion flag (done_r) is set to 0.
If the shift count register (i) is equal to 16, indicating the completion of the multiplication operation, the multiplication completion flag (done_r) is set to 1.
If the shift count register (i) is equal to 17, the multiplication completion flag (done_r) is reset to 0.
Shift and accumulate operation:
On every positive edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the module performs the shift and accumulate operation.
If the reset signal (rst_n) is low, indicating a reset condition, the multiplicand register (areg), multiplier register (breg), and product register (yout_r) are reset to 0.
If the start signal is active (start), the module starts the multiplication operation.
When the shift count register (i) is 0, the multiplicand (ain) and multiplier (bin) are stored in the respective registers (areg and breg).
For shift counts greater than 0 and less than 17, if the bit at position i-1 in the multiplicand register (areg) is high, the product register (yout_r) accumulates the shifted value of the multiplier register (breg) by shifting it left by i-1 positions and appending zeros at the least significant bit positions.
Output assignment:
The product output (yout) is assigned the value of the product register (yout_r).
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = multi_16bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
module multi_16bit(
input clk, // Chip clock signal.
input rst_n, // Active-low reset signal. Defined as 0 for chip reset; defined as 1 for reset signal inactive.
input start, // Chip enable signal.
input [15:0] ain, // Input a (multiplicand) with a data width of 16 bits.
input [15:0] bin, // Input b (multiplier) with a data width of 16 bits.
output [31:0] yout, // Product output with a data width of 32 bits.
output done // Chip output flag signal. Defined as 1 indicates multiplication operation completion.
);
module tb_multi_16bit;
reg clk;
reg rst_n;
reg start;
reg [15:0] ain;
reg [15:0] bin;
wire [31:0] yout;
wire done;
integer i; // Declare the loop variable here
integer fail_count = 0; // Declare a variable to count the failures
integer timeout; // Declare a timeout counter here
reg [31:0] expected_product; // Declare a variable to store the expected product
// Instantiate the module
multi_16bit uut (
.clk(clk),
.rst_n(rst_n),
.start(start),
.ain(ain),
.bin(bin),
.yout(yout),
.done(done)
);
// Clock generation
always begin
#5 clk = ~clk;
end
// Randomize inputs and check output
initial begin
clk = 0; // Initialize clock
rst_n = 1; // De-assert reset
start = 0; // Initialize start
// Perform reset
rst_n = 0;
for (i = 0; i < 100; i = i + 1) begin
#100;
rst_n = 1;
#50;
ain = $random;
bin = $random;
#50;
start = 1; // Start the operation
while(done !== 1) begin
#10;
end
expected_product = ain * bin;
if (done == 1) begin
fail_count = (yout == expected_product)? fail_count:fail_count+1;
end
start = 0; // Stop the operation
rst_n = 0;
#100;
end
if (fail_count == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d / 100 failures===========", fail_count);
end
$finish;
end
initial begin
#50000;
$finish;
end
endmodule
\ No newline at end of file
module verified_multi_16bit(
input clk, // Chip clock signal.
input rst_n, // Active-low reset signal. Defined as 0 for chip reset; defined as 1 for reset signal inactive.
input start, // Chip enable signal.
input [15:0] ain, // Input a (multiplicand) with a data width of 16 bits.
input [15:0] bin, // Input b (multiplier) with a data width of 16 bits.
output [31:0] yout, // Product output with a data width of 32 bits.
output done // Chip output flag signal. Defined as 1 indicates multiplication operation completion.
);
reg [15:0] areg; // Multiplicand a register.
reg [15:0] breg; // Multiplier b register.
reg [31:0] yout_r; // Product register.
reg done_r;
reg [4:0] i; // Shift count register.
//------------------------------------------------
// Data bit control
always @(posedge clk or negedge rst_n)
if (!rst_n) i <= 5'd0;
else if (start && i < 5'd17) i <= i + 1'b1;
else if (!start) i <= 5'd0;
//------------------------------------------------
// Multiplication completion flag generation
always @(posedge clk or negedge rst_n)
if (!rst_n) done_r <= 1'b0;
else if (i == 5'd16) done_r <= 1'b1; // Multiplication completion flag
else if (i == 5'd17) done_r <= 1'b0; // Flag reset
assign done = done_r;
//------------------------------------------------
// Dedicated register for shift and accumulate operation
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
areg <= 16'h0000;
breg <= 16'h0000;
yout_r <= 32'h00000000;
end
else if (start) begin // Start operation
if (i == 5'd0) begin // Store multiplicand and multiplier
areg <= ain;
breg <= bin;
end
else if (i > 5'd0 && i < 5'd17) begin
if (areg[i-1])
yout_r <= yout_r + ({16'h0000, breg} << (i-1)); // Accumulate and shift
end
end
end
assign yout = yout_r;
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement an 8-bit Radix-4 booth multiplier that performs the multiplication of two 8-bit inputs (a and b) using the Booth algorithm. It utilizes a clock signal (clk), and a reset signal (reset), and provides the product output (p) and a ready signal (rdy). The ready signal (rdy) is set to 1 to indicate the completion of the multiplication process.
Module name:
multi_booth_8bit
Input ports:
clk: Clock signal used for synchronous operation.
reset: Reset signal used to initialize the multiplier module.
a: 8-bit input representing the multiplicand.
b: 8-bit input representing the multiplier.
Output ports:
p: 16-bit output representing the product of the multiplication.
rdy: Ready signal indicating the completion of the multiplication operation.
Implementation:
On the positive edge of the clock signal (clk) or the positive edge of the reset signal (reset), the module performs the multiplication process.
If the reset signal (reset) is high, two 16-bit registers multiplier <= {{8{a[7]}}, a} and multiplicand <= {{8{b[7]}}, b}.
If the reset signal (reset) is low, indicating normal operation, the module checks if the counter (5bit ctr) is less than 16.
If the counter (ctr) is less than 16, the multiplicand register (multiplicand) is left-shifted by 1 to simulate the Booth algorithm's shifting operation.
If the current bit of the multiplier register (multiplier[ctr]) is 1, indicating a positive Booth encoding, the product register (p) accumulates the value of the multiplicand register (multiplicand).
The counter (ctr) is incremented by 1. Once the counter (ctr) reaches 16, indicating the completion of the multiplication process, the ready signal (rdy) is set to 1.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = multi_booth_8bit
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns / 1ps
module multi_booth_8bit (p, rdy, clk, reset, a, b);
10
5 5
2 3
10 1
10 2
20 20
-128 2
10 -128
-1 -1
10 0
0 2
\ No newline at end of file
`timescale 1ns/1ns
`define width 8
`define TESTFILE "test_data.dat"
module booth4_mul_tb () ;
reg signed [`width-1:0] a, b;
reg clk, reset;
wire signed [2*`width-1:0] p;
wire rdy;
integer total, err;
integer i, s, fp, numtests;
wire signed [2*`width-1:0] ans = a*b;
multi_booth_8bit dut( .clk(clk),
.reset(reset),
.a(a),
.b(b),
.p(p),
.rdy(rdy));
// Set up 10ns clock
always #5 clk = ~clk;
task apply_and_check;
input [`width-1:0] ain;
input [`width-1:0] bin;
begin
// Set the inputs
a = ain;
b = bin;
// Reset the DUT for one clock cycle
reset = 1;
@(posedge clk);
// Remove reset
#1 reset = 0;
while (rdy == 0) begin
@(posedge clk); // Wait for one clock cycle
end
if (p == ans) begin
// $display($time, " Passed %d * %d = %d", a, b, p);
end else begin
// $display($time, " Fail %d * %d: %d instead of %d", a, b, p, ans);
err = err + 1;
end
total = total + 1;
end
endtask // apply_and_check
initial begin
clk = 1;
total = 0;
err = 0;
// Get all inputs from file: 1st line has number of inputs
fp = $fopen(`TESTFILE, "r");
s = $fscanf(fp, "%d\n", numtests);
// Sequences of values pumped through DUT
for (i=0; i<numtests; i=i+1) begin
s = $fscanf(fp, "%d %d\n", a, b);
apply_and_check(a, b);
end
if (err > 0) begin
$display("=========== Failed ===========");
end else begin
$display("===========Your Design Passed===========");
end
$finish;
end
endmodule
\ No newline at end of file
`timescale 1ns / 1ps
module verified_multi_booth_8bit (p, rdy, clk, reset, a, b);
input clk, reset;
input [7:0] a, b;
output [15:0] p;
output rdy;
reg [15:0] p;
reg [15:0] multiplier;
reg [15:0] multiplicand;
reg rdy;
reg [4:0] ctr;
always @(posedge clk or posedge reset) begin
if (reset)
begin
rdy <= 0;
p <= 0;
ctr <= 0;
multiplier <= {{8{a[7]}}, a};
multiplicand <= {{8{b[7]}}, b};
end
else
begin
if(ctr < 16)
begin
multiplicand <= multiplicand << 1;
if (multiplier[ctr] == 1)
begin
p <= p + multiplicand;
end
ctr <= ctr + 1;
end
else
begin
rdy <= 1;
end
end
end //End of always block
endmodule
\ No newline at end of file
Please act as a professional verilog designer.
Implement the design of 4bit unsigned number pipeline multiplier. It consists of two levels of registers to store intermediate values and control the multiplication process.
Module name:
multi_pipe_4bit
Input ports:
clk: Clock signal used for synchronous operation.
rst_n: Active-low reset signal. Defined as 0 for chip reset and 1 for reset signal inactive.
mul_a: Input signal representing the multiplicand with a data width of "size" bits.
mul_b: Input signal representing the multiplier with a data width of "size" bits.
Output ports:
mul_out: Product output signal with a data width of 2*size bits.
Parameter:
size = 4
Implementation:
Extension of input signals:
The input signals (mul_a and mul_b) are extended by adding "size" number of zero bits at the most significant bit positions.
Multiplication operation:
The module uses a generate block to perform multiplication for each bit position of the multiplier (mul_b) and generate the partial products.
For each bit position i from 0 to size-1, the partial product is calculated as follows:
If the corresponding bit in the multiplier is 1, the multiplicand is left-shifted by i positions.
If the corresponding bit in the multiplier is 0, the partial product is set to 0 ('d0).
Add of partial products:
The module uses registers to store the intermediate sum values.
On the positive edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the module performs add operations.
If the reset signal (rst_n) is low, indicating a reset condition, the registers are set to 0.
If the reset signal (rst_n) is high, the registers are updated with the sum of the corresponding partial products.
Final product calculation:
On the positive edge of the clock signal (clk) or the falling edge of the reset signal (rst_n), the module calculates the final product.
If the reset signal (rst_n) is low, indicating a reset condition, the product output (mul_out) is set to 0.
If the reset signal (rst_n) is high, the product output (mul_out) is updated with the sum of registers.
Give me the complete code.
.PHONY: vcs sim clean
TEST_DESIGN = multi_pipe
vcs:
vcs -sverilog +v2k -timescale=1ns/1ns \
-debug_all \
-l compile.log -full64 \
${TEST_DESIGN}.v testbench.v
sim:
./simv -l run.log
clean:
rm -rf *.log csrc simv* *.key *.vpd DVEfiles coverage *.vdb output.txt
`timescale 1ns/1ns
module multi_pipe_4bit#(
parameter size = 4
)(
input clk ,
input rst_n ,
input [size-1:0] mul_a ,
input [size-1:0] mul_b ,
output reg [size*2-1:0] mul_out
);
`timescale 1ns/1ns
module multi_pipe_tb;
reg clk;
reg rst_n;
reg [3:0] mul_a;
reg [3:0] mul_b;
wire [7:0] mul_out;
wire signed [7:0] perfect = mul_a*mul_b;
// Instantiate the DUT (Design Under Test)
multi_pipe_4bit #(.size(4)) dut (
.clk(clk),
.rst_n(rst_n),
.mul_a(mul_a),
.mul_b(mul_b),
.mul_out(mul_out)
);
// Generate clock
always #5 clk = ~clk;
integer fail_count =0;
integer i=0;
initial begin
// Initialize inputs
clk = 0;
rst_n = 0;
mul_a = 4'b0;
mul_b = 4'b0;
// Wait for a few clock cycles for reset to settle
#10;
// Apply reset
rst_n = 1;
// Perform test case
for (i = 0; i < 100; i = i + 1) begin
mul_a = $random;
mul_b = $random;
#10;
// without pipeline
fail_count = (perfect == mul_out)? fail_count+1:fail_count;
#20;
// $display("%d, %d, %d, %d", mul_a, mul_b, perfect, mul_out);
fail_count = (perfect == mul_out)? fail_count:fail_count+1;
end
if (fail_count == 0) begin
$display("===========Your Design Passed===========");
end
else begin
$display("===========Test completed with %d / 100 failures===========", fail_count);
end
$finish;
end
endmodule
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment