Modules and port correspond to the fundamental code scope and the ability to connect two different blocks of codes in Verilog. Module is what you can call the "shell" of the verilog code. This module again has signals/pins which are called ports that are declared inside the module itself. These pins are a direct medium to connect different modules togather to create a larger functional block.
Keywords associated with modules & ports are listed below:-
module
endmodule
input
output
inout
A few other keywords associated with module concepts are listed below:-
generate
endgenerate
parameter
localparam
defparam
module NbitAND#(parameter N=2)(input wire[N-1:0] ip,output op); assign op = &(ip); // reduction AND operator endmodule
module NbitNAND#(parameter M=2)(input wire[M-1:0]ip,output op); wire and_out; assign op = ~ and_out; NbitAND #(M) ANDgate(.ip(ip),.op(and_out)); endmodule module test; bit[7:0] a,b; wire out_and,out_nand; NbitAND #(3) AND_3b (.ip(a[2:0]),.op(out_and)); NbitNAND #(3) NAND_3b (.ip(b[2:0]),.op(out_nand)); initial begin for(int i=0 ; i<8; i++) begin a = i; b = i; #10; $display($time," AND GATE:: input=%0b output=%0b",a,out_and); $display($time," NAND GATE:: input=%0b output=%0b",b,out_nand); end $finish; end endmodule
module Mstage_siso#(parameter M=2) ( input ip, output op, input clk,rst_n ); reg [M-1:0]temp; assign op = temp[0] ; always @(posedge clk) begin if(!rst_n) //active_low rst begin temp <= 0; end else begin temp = temp >> 1; temp[M-1] <= ip; end end endmodule module test; reg clk=0; reg rst_n = 1; reg ip; wire op; Mstage_siso #(8) siso_8stage(ip,op,clk,rst_n); always clk = #(5) ~clk; initial begin @(negedge clk); rst_n <= 0; ip <= 0; @(negedge clk); rst_n <= 1; for(int i=0 ; i<16 ; i++) begin @(posedge clk); ip = i[3:2]; end #50; $finish; end initial begin $dumpfile("eg31.vcd"); $dumpvars(0,test); end endmodule
//code 2x1 mux module mux2x1 (input [1:0]ip,input sel ,output op); assign op = ip[sel]; endmodule
module Nx1_mux#(parameter N=4) ( input [N-1:0] ip, input [$clog2(N)-1:0] sel, output op ); wire [N-1:0]temp_out[$clog2(N)]; wire [$clog2(N)-1:0] sel_t; assign op = temp_out[0][0]; genvar gen_k; generate for(gen_k=0 ; gen_k < $clog2(N) ; gen_k++) begin assign sel_t[gen_k] = sel[($clog2(N)-1)-gen_k]; end endgenerate genvar gen_i,gen_j; generate for(gen_j= N/2 ; gen_j > 0 ; gen_j = gen_j/2 ) begin : gen_block1 for(gen_i=0 ; gen_i<gen_j ; gen_i++) begin:gen_block2 if(gen_j==N/2) begin mux2x1 u_2x1_mux(.ip(ip[gen_i*2+:2]),.sel(sel_t[$clog2(gen_j)]),.op(temp_out[$clog2(gen_j)][gen_i])); end else begin mux2x1 u_2x1_mux(.ip(temp_out[$clog2(gen_j)+1][(gen_i*2)+:2]),.sel(sel_t[$clog2(gen_j)]),.op(temp_out[$clog2(gen_j)][gen_i])); end end end endgenerate endmodule module test; reg [15:0]ip; reg [3:0] sel; wire op; Nx1_mux #(16) u_Nx1_mux (ip,sel,op); initial begin ip='h5a10; for(int i=0 ;i<16 ; i++) begin sel = i; #5; $display("sel=%0d op=%0b",sel,op); end end initial begin $dumpfile("eg32.vcd"); $dumpvars(0,test); end endmodule
//M bit N stage PISO module Mb_Nstage_PISO #(parameter M=4, N=8) ( input clk,rst_n,en, input [M-1:0] ip, output op ); reg [N-1:0]temp; assign op = temp[0]; always@(posedge clk) begin if(!rst_n) //active low reset begin temp <= 0; end else if(en) begin temp[N-1:M] <= ip; end else begin temp = temp >> 1; end end endmodule module test; reg clk=0,en=0; reg rst_n = 1; reg [3:0]ip; wire op; Mb_Nstage_PISO #(4,8) u_4b_8stage_PISO(clk,rst_n,en,ip,op); always clk = #(5) ~clk; initial begin @(negedge clk); rst_n = 0; ip = 5; @(negedge clk); rst_n = 1; @(posedge clk); en =1; for(int i=0 ; i<16 ; i++) begin @(posedge clk); en=0; @(posedge clk); end #50; $finish; end initial begin $dumpfile("eg33.vcd"); $dumpvars(0,test); end endmodule
//NX1 or 1XN mux-demux circuit module mux_demux#(parameter N=2 ,M="M") ( input [N-1:0] ip, input [$clog2(N)-1:0] sel, output [N-1:0] op ); reg [N-1:0] op_t; assign op = op_t; always@(*) begin if(M=="M")// MUX begin op_t[0] = ip[sel]; end else //DEMUX begin op_t = 0; op_t[sel] = ip[0]; end end endmodule module test; reg [3:0]ip_m,ip_d; wire [3:0]op_m,_op_d; reg [1:0] sel_m,sel_d; mux_demux #(4,"M") u_mux (.ip(ip_m),.sel(sel_m),.op(op_m)); mux_demux #(4,"D") u_demux (.ip(ip_d),.sel(sel_d),.op(op_d)); initial begin ip_m = 'ha; ip_d[0] = 1; for(int i=0 ;i<4 ; i++) begin sel_m = i; sel_d = i; #5; $display("MUX :: ip=%0b sel=%0b op=%0b",ip_m,sel_m,op_m[0]); $display("DEMUX :: ip=%0b sel=%0b op=%0b",ip_d[0],sel_d,op_d); end $finish; end endmodule
//N bit round robin arbiter module Nb_arbiter #(parameter N=4) ( input clk,rst_n, input [N-1:0] req, output reg [N-1:0] grant ); reg cycle_ip=1; reg [N-1:0] latch_grant=0; function bit can_grant(int index); if(cycle_ip==1) begin if(latch_grant[index]==0) begin can_grant = 1'b1; end else begin can_grant = 1'b0; end end else begin can_grant = 1'b1; end endfunction always@(posedge clk) begin if(!rst_n) begin grant<=0; end else begin for(int i=0 ; i<N ; i++) begin if(req[i] && grant[i]==0 && can_grant(i)) begin cycle_ip <= 1; grant <= 0; grant[i] <= 1; latch_grant[i] <=1; if(i==N-1) begin cycle_ip <= 0; latch_grant <= 0; end break ; end else if(req[i] && grant[i]==0 && i==0) begin latch_grant <= 0; grant <= 0; grant[i] <= 1; latch_grant[i] <=1; end else begin grant <= 0; end end end end endmodule module test; reg clk=0,rst_n; reg [3:0]req; wire [3:0]grant; always clk = #5 ~clk; Nb_arbiter #(4) u_arbiter (clk,rst_n,req,grant); initial begin rst_n <= 0; @(posedge clk); @(negedge clk); rst_n <= 1; @(negedge clk); req <= 1; @(negedge clk); req <= 2; @(negedge clk); req <= 4; #100; $finish; end initial begin $dumpfile("eg35.vcd"); $dumpvars(0,test); end endmodule
//Nb M depth fifo module Nb_2_pow_Mdepth_fifo#(parameter N=2 , M=4) ( input wr_clk,rd_clk, input rst_n, output full,empty, input wr_en,rd_en, input [N-1:0] wrdata, output reg [N-1:0] rddata ); reg[N-1:0] fifo[2**M]; integer wr_ptr,rd_ptr; assign full = (wr_ptr==(2**M)); assign empty = (wr_ptr==0); always@(posedge wr_clk) begin if(!rst_n) begin wr_ptr=0; for(int i=0 ; i<2**M; i++) begin fifo[i] <= 0; end end else if(wr_en && full==0) begin fifo[wr_ptr] <= wrdata; wr_ptr <= wr_ptr +1; end end always@(posedge rd_clk) begin if(!rst_n) begin rd_ptr <= 0; end else if(rd_en && empty==0) begin rddata <= fifo[rd_ptr]; rd_ptr <= rd_ptr+1; wr_ptr <= wr_ptr-1; end end endmodule module test; reg wr_clk=0,rd_clk=0,rst_n,wr_en,rd_en; reg[1:0] wrdata; wire [1:0] rddata; wire full,empty; Nb_2_pow_Mdepth_fifo #(2,2) u_fifo(wr_clk,rd_clk,rst_n,full,empty,wr_en,rd_en,wrdata,rddata); always wr_clk = #5 ~wr_clk; always rd_clk = #5 ~rd_clk; initial begin rst_n=0; @(negedge wr_clk); @(negedge wr_clk); rst_n=1; @(negedge wr_clk); wr_en=1; for(int i=0 ; i<4 ; i++) begin wrdata = i; @(negedge wr_clk); end wr_en=0; #20; rd_en=1; for(int i=0 ; i<5 ; i++) begin @(negedge wr_clk); end rd_en=0; #20; $finish; end initial begin $dumpfile("eg36.vcd"); $dumpvars(0,test); end endmodule