module dataProcess (
din ,
dout ,
dio
);
input din ;
output dout ;
inout dio ;
wire din ;
wire dout ;
// reg dout ;
wire dio ;
endmodule
2) combinational logic
input clk ;
input mode ;
output sclk ;
wire clk ;
wire mode ;
wire sclk ;
reg clk_en;
// generate sclk
assign sclk = (clk_en == 1'b1) ? clk : 1'b0;
always @(mode)
//verilog 2000
//always @(*)
begin
case (mode)
0 : begin
clk_en = 1'b0;
end
1 : begin
clk_en = 1'b1;
end
default : begin
clk_en = 1'b0;
end
endcase
end
endmodule
3) timing logic
module dff_1 (
clk ,
rst_n ,
din ,
dout
);
input clk ;
input rst_n ;
input din ;
output dout ;
wire clk ;
wire rst_n ;
wire din ;
reg dout ;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0)
dout <= 1'b0;
else
dout <= din;
end
endmodule
4) tristate gate
module dataProcess (
sclk ,
rst_n ,
rw ,
sdio
);
input sclk ;
input rst_n ;
input rw ;
inout sdio ;
wire sclk ;
wire rst_n ;
wire rw ;
wire sdio ;
wire sdi ;
reg sdo ;
reg sdo_en ;
reg [7:0] data ;
//generate sdio
assign sdio = (sdo_en == 1'b1) ? sdo : 1'bz;
assign sdi = sdio;
always @(posedge sclk or negedge rst_n) begin
if(rst_n == 1'b0)
data <= 'h0;
else begin
if(rw == 1'b0)
data <= {data[6:0], sdi};
else
data <= {data[6:0], 1'b0};
end
end
always @(posedge sclk or negedge rst_n) begin
if(rst_n == 1'b0) begin
sdo <= 1'b0;
sdo_en <= 1'b0;
end
else begin
if(rw == 1'b1) begin
sdo <= data[7];
sdo_en <= 1'b1;
end
else begin
sdo <= 1'b0;
sdo_en <= 1'b0;
end
end
end
endmodule
5) module calling function
///////////////////////////////////////////////////////
// module user_pkg contains the function
///////////////////////////////////////////////////////
module user_pkg;
function [31:0] factorial;
input [3:0] operand;
reg [3:0] index ;
begin
factorial = operand ? 1 : 0;
for(index = 2; index <= operand; index = index + 1)
factorial = index * factorial;
end
endfunction
endmodule
///////////////////////////////////////////////////////
// module calling package
///////////////////////////////////////////////////////
module test_package (
n ,
result
);
input [3:0 ] n ;
output [31:0] result ;
wire [3:0 ] n ;
reg [31:0] result ;
always @(n) begin
result = n * user_pkg.factorial(n) / ((n * 2) + 1);
end
endmodule
// module user_pkg contains the function
///////////////////////////////////////////////////////
module user_pkg;
function [31:0] factorial;
input [3:0] operand;
reg [3:0] index ;
begin
factorial = operand ? 1 : 0;
for(index = 2; index <= operand; index = index + 1)
factorial = index * factorial;
end
endfunction
endmodule
///////////////////////////////////////////////////////
// module calling package
///////////////////////////////////////////////////////
module test_package (
n ,
result
);
input [3:0 ] n ;
output [31:0] result ;
wire [3:0 ] n ;
reg [31:0] result ;
always @(n) begin
result = n * user_pkg.factorial(n) / ((n * 2) + 1);
end
endmodule
6) module calling task
///////////////////////////////////////////////////////
// module user_pkg contains task
///////////////////////////////////////////////////////
module user_pkg;
task segment_dec;
input [3:0] bcd ;
output [6:0] segment;
begin
case(bcd)
//decode from bcd to segment
4'h0: segment = 7'b1000000;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
default: segment = 7'b1000000;
endcase
end
endtask
endmodule
///////////////////////////////////////////////////////
// module calling task
///////////////////////////////////////////////////////
module bcd2segment (
bcd ,
segment
);
input [3:0] bcd ;
output [6:0] segment ;
wire [3:0] bcd ;
reg [6:0] segment ;
always @(bcd) begin
user_pkg.segment_dec(bcd, segment);
end
endmodule
7) parameter
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
clk ,
rst_n ,
clk_out
);
parameter N = 12499999;
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
reg clk_out ;
integer clk_cnt;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
clk_cnt <= 0;
clk_out <= 1'b0;
end
else begin
//when counter reaches to half second,
//need to reset the counter to 0
if(clk_cnt == N) begin
clk_cnt <= 0;
clk_out <= ~clk_out;
end
else begin
clk_cnt <= clk_cnt + 1;
clk_out <= clk_out;
end
end
end
endmodule
/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
clk ,
rst_n ,
clk_out
);
parameter N = 20;
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
wire clk_out ;
//instance clock dividor
clk_div #(
//verilog 2000
//.N(N)
N
) u_clk_div (
.clk (clk ) ,
.rst_n (rst_n ) ,
.clk_out (clk_out )
);
endmodule
8) instance module
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
clk ,
rst_n ,
clk_out
);
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
reg clk_out ;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
clk_out <= 1'b0;
end
else begin
clk_out <= ~clk_out;
end
end
endmodule
/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
clk ,
rst_n ,
clk_out
);
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
wire clk_out ;
//instance clock dividor
clk_div u_clk_div (
.clk (clk ) ,
.rst_n (rst_n ) ,
.clk_out (clk_out )
);
endmodule
9) ifdef
`define M7 7
module bcd2segment (
bcd ,
segment
);
input [3:0 ] bcd ;
output [`M7-1:0] segment;
wire [3:0 ] bcd ;
reg [`M7-1:0] segment;
always @(bcd) begin
case(bcd)
`ifdef M7
//decode from bcd to segment
4'h0: segment = 7'b1111111;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
//for other unknown selectors, set counter to 0
default: segment = 7'b1111111;
`else
//decode from bcd to segment
4'h0: segment = 8'b11111111;
4'h1: segment = 8'b11111001;
4'h2: segment = 8'b10100100;
4'h3: segment = 8'b10110000;
4'h4: segment = 8'b10011001;
4'h5: segment = 8'b10010010;
4'h6: segment = 8'b10000010;
4'h7: segment = 8'b11111000;
4'h8: segment = 8'b10000000;
4'h9: segment = 8'b10010000;
//for other unknown selectors, set counter to 0
default: segment = 8'b11111111;
`endif
endcase
end
endmodule
///////////////////////////////////////////////////////
// module user_pkg contains task
///////////////////////////////////////////////////////
module user_pkg;
task segment_dec;
input [3:0] bcd ;
output [6:0] segment;
begin
case(bcd)
//decode from bcd to segment
4'h0: segment = 7'b1000000;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
default: segment = 7'b1000000;
endcase
end
endtask
endmodule
///////////////////////////////////////////////////////
// module calling task
///////////////////////////////////////////////////////
module bcd2segment (
bcd ,
segment
);
input [3:0] bcd ;
output [6:0] segment ;
wire [3:0] bcd ;
reg [6:0] segment ;
always @(bcd) begin
user_pkg.segment_dec(bcd, segment);
end
endmodule
7) parameter
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
clk ,
rst_n ,
clk_out
);
parameter N = 12499999;
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
reg clk_out ;
integer clk_cnt;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
clk_cnt <= 0;
clk_out <= 1'b0;
end
else begin
//when counter reaches to half second,
//need to reset the counter to 0
if(clk_cnt == N) begin
clk_cnt <= 0;
clk_out <= ~clk_out;
end
else begin
clk_cnt <= clk_cnt + 1;
clk_out <= clk_out;
end
end
end
endmodule
/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
clk ,
rst_n ,
clk_out
);
parameter N = 20;
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
wire clk_out ;
//instance clock dividor
clk_div #(
//verilog 2000
//.N(N)
N
) u_clk_div (
.clk (clk ) ,
.rst_n (rst_n ) ,
.clk_out (clk_out )
);
endmodule
8) instance module
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
clk ,
rst_n ,
clk_out
);
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
reg clk_out ;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
clk_out <= 1'b0;
end
else begin
clk_out <= ~clk_out;
end
end
endmodule
/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
clk ,
rst_n ,
clk_out
);
input clk ;
input rst_n ;
output clk_out ;
wire clk ;
wire rst_n ;
wire clk_out ;
//instance clock dividor
clk_div u_clk_div (
.clk (clk ) ,
.rst_n (rst_n ) ,
.clk_out (clk_out )
);
endmodule
9) ifdef
`define M7 7
module bcd2segment (
bcd ,
segment
);
input [3:0 ] bcd ;
output [`M7-1:0] segment;
wire [3:0 ] bcd ;
reg [`M7-1:0] segment;
always @(bcd) begin
case(bcd)
`ifdef M7
//decode from bcd to segment
4'h0: segment = 7'b1111111;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
//for other unknown selectors, set counter to 0
default: segment = 7'b1111111;
`else
//decode from bcd to segment
4'h0: segment = 8'b11111111;
4'h1: segment = 8'b11111001;
4'h2: segment = 8'b10100100;
4'h3: segment = 8'b10110000;
4'h4: segment = 8'b10011001;
4'h5: segment = 8'b10010010;
4'h6: segment = 8'b10000010;
4'h7: segment = 8'b11111000;
4'h8: segment = 8'b10000000;
4'h9: segment = 8'b10010000;
//for other unknown selectors, set counter to 0
default: segment = 8'b11111111;
`endif
endcase
end
endmodule
10) parameter used as data width
`define M7
module bcd2segment (
bcd ,
segment
);
`ifdef M7
parameter M = 7;
`else
parameter M = 8;
`endif
input [3:0 ] bcd ;
output [M-1:0] segment;
wire [3:0 ] bcd ;
reg [M-1:0] segment;
always @(bcd) begin
case(bcd)
`ifdef M7
//decode from bcd to segment
4'h0: segment = 7'b1111111;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
//for other unknown selectors, set counter to 0
default: segment = 7'b1111111;
`else
//decode from bcd to segment
4'h0: segment = 8'b11111111;
4'h1: segment = 8'b11111001;
4'h2: segment = 8'b10100100;
4'h3: segment = 8'b10110000;
4'h4: segment = 8'b10011001;
4'h5: segment = 8'b10010010;
4'h6: segment = 8'b10000010;
4'h7: segment = 8'b11111000;
4'h8: segment = 8'b10000000;
4'h9: segment = 8'b10010000;
//for other unknown selectors, set counter to 0
default: segment = 8'b11111111;
`endif
endcase
end
endmodule
31) testbench
/////////////////////////////////////////////////////////////////
//DUT
/////////////////////////////////////////////////////////////////
module adder (
clk ,
rst_n ,
enable ,
a ,
b ,
s ,
cout
);
input clk ;
input rst_n ;
input enable ;
input [3:0] a ;
input [3:0] b ;
output [3:0] s ;
output cout ;
wire clk ;
wire rst_n ;
wire enable ;
wire [3:0] a ;
wire [3:0] b ;
wire [3:0] s ;
wire cout ;
reg [4:0] sum ;
assign s = sum[3:0];
assign cout = sum[4];
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0)
sum <= 5'h0;
else begin
if(enable == 1)
sum <= a + b;
end
end
endmodule
/////////////////////////////////////////////////////////////////
//tb
/////////////////////////////////////////////////////////////////
module tb_adder();
reg clk ;
reg rst_n ;
reg enable ;
reg [3:0] a ;
reg [3:0] b ;
wire [3:0] s ;
wire cout ;
adder u_adder (
.clk (clk ) ,
.rst_n (rst_n ) ,
.enable (enable ) ,
.a (a ) ,
.b (b ) ,
.s (s ) ,
.cout (cout )
);
initial begin
clk = 1'b0;
forever #6.67 clk = ~clk;
end
initial begin
rst_n = 1'b0;
#600;
rst_n = 1'b1;
end
integer i;
integer j;
initial begin
enable <= 1'b0;
a <= 'h0;
b <= 'h0;
@(posedge rst_n);
@(negedge clk)
for(i=0; i<16; i=i+1) begin
for(j=0; j<16; j=j+1) begin
@(negedge clk);
a = i[3:0];
b = j[3:0];
enable = 1'b0;
@(posedge clk);
#1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
@(negedge clk);
enable = 1'b1;
@(posedge clk);
#1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
end
end
#100;
$finish();
end
endmodule
`define M7
module bcd2segment (
bcd ,
segment
);
`ifdef M7
parameter M = 7;
`else
parameter M = 8;
`endif
input [3:0 ] bcd ;
output [M-1:0] segment;
wire [3:0 ] bcd ;
reg [M-1:0] segment;
always @(bcd) begin
case(bcd)
`ifdef M7
//decode from bcd to segment
4'h0: segment = 7'b1111111;
4'h1: segment = 7'b1111001;
4'h2: segment = 7'b0100100;
4'h3: segment = 7'b0110000;
4'h4: segment = 7'b0011001;
4'h5: segment = 7'b0010010;
4'h6: segment = 7'b0000010;
4'h7: segment = 7'b1111000;
4'h8: segment = 7'b0000000;
4'h9: segment = 7'b0010000;
//for other unknown selectors, set counter to 0
default: segment = 7'b1111111;
`else
//decode from bcd to segment
4'h0: segment = 8'b11111111;
4'h1: segment = 8'b11111001;
4'h2: segment = 8'b10100100;
4'h3: segment = 8'b10110000;
4'h4: segment = 8'b10011001;
4'h5: segment = 8'b10010010;
4'h6: segment = 8'b10000010;
4'h7: segment = 8'b11111000;
4'h8: segment = 8'b10000000;
4'h9: segment = 8'b10010000;
//for other unknown selectors, set counter to 0
default: segment = 8'b11111111;
`endif
endcase
end
endmodule
31) testbench
/////////////////////////////////////////////////////////////////
//DUT
/////////////////////////////////////////////////////////////////
module adder (
clk ,
rst_n ,
enable ,
a ,
b ,
s ,
cout
);
input clk ;
input rst_n ;
input enable ;
input [3:0] a ;
input [3:0] b ;
output [3:0] s ;
output cout ;
wire clk ;
wire rst_n ;
wire enable ;
wire [3:0] a ;
wire [3:0] b ;
wire [3:0] s ;
wire cout ;
reg [4:0] sum ;
assign s = sum[3:0];
assign cout = sum[4];
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0)
sum <= 5'h0;
else begin
if(enable == 1)
sum <= a + b;
end
end
endmodule
/////////////////////////////////////////////////////////////////
//tb
/////////////////////////////////////////////////////////////////
module tb_adder();
reg clk ;
reg rst_n ;
reg enable ;
reg [3:0] a ;
reg [3:0] b ;
wire [3:0] s ;
wire cout ;
adder u_adder (
.clk (clk ) ,
.rst_n (rst_n ) ,
.enable (enable ) ,
.a (a ) ,
.b (b ) ,
.s (s ) ,
.cout (cout )
);
initial begin
clk = 1'b0;
forever #6.67 clk = ~clk;
end
initial begin
rst_n = 1'b0;
#600;
rst_n = 1'b1;
end
integer i;
integer j;
initial begin
enable <= 1'b0;
a <= 'h0;
b <= 'h0;
@(posedge rst_n);
@(negedge clk)
for(i=0; i<16; i=i+1) begin
for(j=0; j<16; j=j+1) begin
@(negedge clk);
a = i[3:0];
b = j[3:0];
enable = 1'b0;
@(posedge clk);
#1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
@(negedge clk);
enable = 1'b1;
@(posedge clk);
#1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
end
end
#100;
$finish();
end
endmodule
No comments:
Post a Comment