1 / 39

COE 405 Logic Design with Behavioral Models of Combinational & Sequential Logic II

This course covers behavioral modeling of ASM, repetitive algorithms, tasks and functions, register file, memory unit, and file I/O system functions and tasks.

jacksonr
Download Presentation

COE 405 Logic Design with Behavioral Models of Combinational & Sequential Logic II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. COE 405 Logic Design with Behavioral Models of Combinational & Sequential Logic II Dr. Aiman H. El-Maleh Computer Engineering Department King Fahd University of Petroleum & Minerals

  2. Outline • Behavioral Modeling of ASM • Repetitive Algorithms • Tasks and Functions • Register File • Memory Unit • File I/O System Functions and Tasks

  3. Behavioral Modeling of ASM module Controller (output reg Clr_P1_P0, Ld_P1_P0, Ld_R0, input En, Ld, clk, rst); parameter S_idle = 2'b00, S_1=2'b01, S_full=2'b10, S_wait=2'b11; reg [1:0] state, next_state; always @(posedge clk) if (rst) state <= S_idle; else state <= next_state; always @(state, En, Ld) begin Clr_P1_P0 = 0; Ld_P1_P0=0; Ld_R0=0; case (state) S_idle: if (En) begin next_state=S_1; Ld_P1_P0=1; end else next_state=S_idle;

  4. Behavioral Modeling of ASM S_1: begin next_state=S_full; Ld_P1_P0=1; end S_full: if (!Ld) next_state=S_wait; else begin Ld_R0=1; if (En) begin next_state=S_1; Ld_P1_P0=1; end else begin next_state=S_idle; Clr_P1_P0=1; end end S_wait: if (!Ld) next_state=S_wait; else begin Ld_R0=1; if (En) begin next_state=S_1; Ld_P1_P0=1; end else begin next_state=S_idle; Clr_P1_P0=1; end end endcase end endmodule

  5. Linear Feedback Shift Register (LFSR)

  6. Linear Feedback Shift Register (LFSR)

  7. Linear Feedback Shift Register (LFSR) module LFSR #(parameter Length=8, initial_state = 8'b1001_0001, //91h parameter [Length: 1] Tap_Coefficient = 8'b1100_1111) (input clock, reset_b, output reg[1:Length] Y); always@ (posedge clock) if (reset_b == 1'b0) Y<= initial_state; else begin Y[1] <= Y[8]; Y[2] <= Tap_Coefficient[7]? Y[1]^Y[8]:Y[1]; Y[3] <= Tap_Coefficient[6]? Y[2]^Y[8]:Y[2]; Y[4] <= Tap_Coefficient[5]? Y[3]^Y[8]:Y[3]; Y[5] <= Tap_Coefficient[4]? Y[4]^Y[8]:Y[4]; Y[6] <= Tap_Coefficient[3]? Y[5]^Y[8]:Y[5]; Y[7] <= Tap_Coefficient[2]? Y[6]^Y[8]:Y[6]; Y[8] <= Tap_Coefficient[1]? Y[7]^Y[8]:Y[7]; end endmodule

  8. Repetitive Algorithms • for loop: • for (initial_statement; control expression; index_statement) statement_for_execution; • initial_statementexecutes once to initialize a register variable (i.e. an integer or reg) that controls the loop • If control_expression is true the statement_for_execution will execute • After the statement_for_executionhas executed, the index_statement will execute (usually to increment a counter) • Then the control expression is checked again and if false the loop terminates.

  9. Linear Feedback Shift Register (LFSR) module LFSR2 #(parameter Length=8, initial_state = 8'b1001_0001, //91h parameter [Length:1] Tap_Coefficient = 8'b1100_1111) (input clock, reset_b, output reg [1:Length] Y); integer k; always@ (posedge clock) if (reset_b == 1'b0) Y<= initial_state; else begin for (k = 2; k <= Length; k = k+1) if (Tap_Coefficient[Length-k+1]==1) Y[k] <= Y[k-1]^Y[Length]; else Y[k] <= Y[k-1]; Y[1] <= Y[Length]; end endmodule

  10. Linear Feedback Shift Register (LFSR) module LFSR3 #(parameter Length=8, initial_state = 8'b1001_0001, //91h parameter [Length:1] Tap_Coefficient = 8'b1100_1111) (input clock, reset_b, output reg [1:Length] Y); integer k; always@ (posedge clock) if (reset_b == 1'b0) Y<= initial_state; else begin for (k = 2; k <= Length; k = k+1) Y[k] <= Tap_Coefficient[Length-k+1]?Y[k-1]^Y[Length]:Y[k-1]; Y[1] <= Y[Length]; end endmodule

  11. Majority module Majority #(parameter size=8, max=4, majority=5) (input [size-1:0] Data, output reg Y); reg [max-1:0] count; integer k; always@ (Data) begin count = 0; for (k=0; k < size; k = k+1) if (Data[k] == 1) count = count + 1; Y = (count >= majority); end endmodule

  12. Adder/Subtracter module ADDSUB #(parameter n=4)(output reg [n-1:0] S, output Cout, input [n-1:0] A, B, input OP); integer i; reg [n:0] C; reg [n-1:0] G,P; assign Cout = C[n];  always @ (A, B, OP) begin  C[0] = OP;  for (i=0; i<n; i=i+1) begin  G[i] = A[i] & (B[i] ^ OP); P[i] = A[i] ^ (B[i] ^ OP); S[i] = P[i] ^ C[i]; C[i+1] = G[i] | P[i] & C[i];  end  end  endmodule

  13. Signed Multiplication module MULC #(parameter N=4) (output reg [N-1:0] HI, LO, input [N-1:0] A, B); integer i; reg [N-1:0] C; reg OVF, Sign; always @(A, B) begin HI = 0; LO = B; for (i=0; i<N; i=i+1) begin if( LO[0] ) begin if ( i==N-1 ) begin C = HI - A; OVF = (HI[N-1] ^ A[N-1]) & (HI[N-1]^C[N-1]); end else begin C = HI + A; OVF = (HI[N-1] ~^ A[N-1]) & (HI[N-1]^C[N-1]); end

  14. Signed Multiplication Sign = OVF ^ C[N-1]; HI = C; end else Sign = HI[N-1]; // LO[0]==0 {HI, LO} = {Sign, HI, LO[N-1:1]}; end // for loop end // always endmodule

  15. Unsigned Division module DIV #(parameter N=4) (output reg [N-1:0] Q, R, input [N-1:0] dividend, diviser); integer i; reg [N-1:0] diff; always @(dividend, diviser) begin Q = dividend; R = 0; for (i=0; i<N; i=i+1) begin {R,Q} = {R,Q} << 1; diff = R - diviser; if( !diff[N-1] ) begin R = diff; Q[0]= 1; end end end endmodule

  16. Repetitive Algorithms • repeat loop • repeat (expression) statement; • executes an associated statement or block of statements a specified number of times unless it is terminated by a disable statement within the activity flow • Example: a repeat loop is used to initialize a memory array word_address = 0; repeat (memory_size) begin memory[word_address]=0; word_address = word_address+1; end

  17. Repetitive Algorithms • while loop • while (expression) statement; • Executes repeatedly while a Boolean expression is true module CountOnes (input [7:0] reg_a, output reg [3:0] count); always@ (reg_a) begin: count_of_1s // declares a named block of statements reg [7:0] temp_reg; count = 0; temp_reg = reg_a; // load a data word while (temp_reg) begin if (temp_reg[0]) count = count + 1; // count = count + temp_reg[0]; temp_reg = temp_reg >> 1; end end endmodule

  18. Clock Generators module clockgen (output reg clock); parameter half_cycle = 50; parameter stop_time = 350; initial begin: clock_loop clock = 0; forever begin #half_cycle clock = 1; #half_cycle clock = 0; end end initial #stop_time disable clock_loop; endmodule

  19. Disable Statement • Disable statement is used to prematurely terminate a named block of procedural statements. Execution is transferred to the statement that immediately follows the named block. module find_first_one (output reg [3:0] index_value, input [15:0] A_word, input trigger); always @(posedge trigger) begin: search_for_1 for (index_value=0; index_value<15; index_value=index_value+1) if (A_word[index_value] == 1) disable search_for_1; end endmodule Not Supported by Synthesis Tools

  20. Tasks and Functions • Tasks create a hierarchical organization of proceduralstatements within a Verilog behavior. • Functions substitute for an expression. • Tasks and functions facilitate a readable style of code, with a single identifier conveying the meaning of many lines of code. • Encapsulation of Verilog code into tasks or functions hides the details of an implementation. • Overall, tasks and functions improve the readability, portability and maintainability of a model.

  21. Tasks • Tasks are declared within a module and they may be referenced from within a cyclic or single-pass behavior. • A task can have parameters passed to it and results of executing a task can be passed back to environment. • When a task is called, copies of parameters in environment are associated with inputs, outputs, and inouts within the task according to order of declaration • The variables in environment are visible to a task. • Local variables may be declared within a task. • A task can call itself.

  22. Tasks • A task must be named and may include declarations of any number of: parameter, input, output, inout, reg, integer, real, time, realtime. • Arguments of a task retain the type they hold in the environment that invokes the task. • All arguments of a task are passed by a value. • The basic syntax of a task is: task [task-id] ([arg]) ; begin [statements] ; end endtask • [arg] is the argument declaration and is similar to port declaration except that the default output data type is reg and the wire data type can not be used as output.

  23. Tasks module adder_task (output reg c_out, output reg [3:0] sum, input [3:0] data_a, data_b, input c_in, clk, reset); always @(posedge clk, posedge reset) if (reset == 1’b1) {c_out, sum} <= 0; else add_values(c_out, sum, data_a, data_b, c_in); taskadd_values (output c_out, output [3:0] sum, input [3:0] data_a, data_b, input c_in); {c_out, sum} <= data_a + data_b + c_in; endtask endmodule

  24. Tasks module adder_task2 (output reg [5:0] sum, input [3:0] data_a, data_b, data_c, data_d, input clk, reset); reg [5:0] sum1, sum2; always @(posedge clk, posedge reset) if (reset == 1) sum = 0; else begin add_values2(sum1, data_a, data_b); add_values2(sum2, data_c, data_d); add_values2(sum, sum1, sum2); end taskadd_values2 (output [5:0] sum, input [5:0] data_a, data_b); sum = data_a + data_b; endtask endmodule

  25. Tasks module eq2task (output reg aeqb, input [1:0] a,b); reg e0, e1; always @* begin equ_task(2, a[0], b[0], e0); equ_task(2, a[1], b[1], e1); aeqb = e0 & e1; end taskequ_task(input integer delay, input i0, i1, output eq); #delay eq = i0 ~^ i1; endtask endmodule

  26. Functions • Verilog functions are declared within a parent module and can be referenced in any valid expression. • A function is implemented by an expression and returns a value at the location of the function’s identifier. • Functions may implement only combinational behavior. • A function may not contain timing controls (#, @, wait), non-blocking statements. • Functions may not invoke a task but they may call other functions but not recursively. • Functions are expanded during synthesis and "flattened”.

  27. Functions • Basic syntax of a function is shown below: • [result-type] is the data type of the returned result (usually reg or integer; default is reg). • Function name is specified by [func-id] • Function value is returned by a statement like: func-id = … ;

  28. Functions • Consider the following module snippet: with one operation repeated 2 times • We can define a function INC and use it. • INC takes a 4-bit input argument and returns a 4-bit result module … … assign X = (A>4) ? A+3 : A; assign Y = (B>4) ? B+3 : B; …. endmodule module … …. assign X = INC(A); assign Y = INC(B); …. function [3:0] INC(input [3:0] T); INC = (T>4) ? T+3 : T; endfunction …. endmodule

  29. Functions • A function could be used to calculate the constants whose values depend on other parameters: Note that the function in this example is evaluated during pre-processing, it does not infer any hardware module modulo_counter #(parameter M=10)( input clk, reset, output reg [log2 (M)-1:0] q ); always @ (posedge clk) if (reset || q==M) q <= 0; else q <= q + 1; functionintegerlog2 (input integer n); integer i; begin log2 = 1; for (i=0; 2**i<n; i=i+1) log2 = i+1; end endfunction endmodule

  30. Functions module arithmetic_unit ( output [4:0] result_1, output [3:0] result_2, input [3:0] operand_1, operand_2); assign result_1 = sum_of_operands (operand_1, operand_2); assign result_2 = largest_operand (operand_1, operand_2); function [4:0] sum_of_operands (input [3:0] operand_1, operand_2); sum_of_operands = operand_1 + operand_2; endfunction function [3:0] largest_operand (input [3:0] operand_1, operand_2); largest_operand = (operand_1 >= operand_2) ? operand_1: operand_2; endfunction endmodule

  31. Register File module Register_File #(parameter word_size=32, addr_size=5) ( output [word_size-1:0] Data_Out_1, Data_Out_2, input [word_size-1:0] Data_In, input [addr_size-1:0] Read_Addr_1, Read_Addr_2, Write_Addr, input Write_Enable, Clock); reg [word_size-1:0] Reg_File[2**addr_size-1:0]; initial begin Reg_File[0]=10; Reg_File[1]=20; end assign Data_Out_1 = Reg_File[Read_Addr_1]; assign Data_Out_2= Reg_File[Read_Addr_2]; always @(posedge Clock) if (Write_Enable==1'b1) Reg_File[Write_Addr] <= Data_In; endmodule

  32. Memory Unit module Memory_Unit #(parameter word_size=8, address_size=4, memory_size=16) (output [word_size-1:0] data_out, input [word_size-1:0] data_in, input [address_size-1:0] address, input clk, write); reg [word_size-1:0] memory[memory_size-1:0]; assign data_out = memory[address]; always @ (posedge clk) if (write) memory[address] <= data_in; endmodule

  33. File I/O System Functions and Tasks • Verilog provides a set of functions and tasks to access external data files. These are extremely useful in testbenches. • A file can be opened and closed by the $fopen and $fclose functions. The simplified syntax of using $fopen is: [mcd_name] = $fopen ( " [file_name] " ) ; • The $fopen returns a 32-bit multichannel descriptor associated with the file. • The descriptor is a 32-bit flag, in which each bit represents a file (i.e., a channel). The LSB is reserved for the standard output (i.e., the console). • When the file is opened successfully, a descriptor is returned with one bit asserted. • For example, 0 . . .0010 is returned for the first opened file, 0 . . .0100 is returned for the second opened file, and so on. The function returns all 0's if the open operation fails.

  34. Writing to an Opened File • Data can be written to an opened file using the following system tasks: $fdisplay, $fwrite, $fstrobe, and $fmonitor. The syntax is: $fdisplay ([mcd_name] , [format_string] , arguement1, arguement2 , …) ; • [format_string] term contains regular characters and "escape sequences“ to specify the format of the corresponding arguments. When the string is displayed, the values of the corresponding arguments are substituted into the string and shown in the designated format. • The commonly used escape sequences include %d, %b, %o, %h, %c, %s, and %g, which are for decimal, binary, octal, hexadecimal, character, string, and real number, respectively.

  35. File Write Example • In the example below a descriptor (both_file) is created by a bitwise or operation over 2 multichannel descriptors. This is used to write text to the console and the log file. module filetest (); integer log_file, both_file; localparam con_file=16'h0000_0001; initial begin log_file = $fopen("my_log"); if (log_file==0) $display("Fail to open file"); // write to console both_file = log_file | con_file; // write to both console and log file $fdisplay(both_file, "Simulation Started"); // write to log file only $fdisplay(log_file, "Writing to log file only"); // write to both console and log file $fdisplay(both_file, "Simulation Ended"); $fclose(log_file); end endmodule

  36. Reading Data from External Files • There are two simple system tasks to retrieve data from an external file: $readmemb and $readmemh • These tasks assume that the external file stores the content of a memory array and reads the content into a variable. • The $readmemb and $readmemh tasks further assume that the content is in the binary and hexadecimal formats, respectively. • The simplified syntax is: $readmemb (" [file-name] " , [mem-variable]) ; $readmemh (“ [file-name] " , [mem-variable]) ; • The following code segment illustrates the retrieval of an 8 by 4 memory array: reg [3:0] v_mem [0:7] ; . . . $readmemb ( “vector.txt" , v_mem) ; The vector.txt file should contain eight 4-bit binary data separated by white spaces.

  37. Example: Using External Files to Specify Test Patterns and to Record Simulation Results module eq2_file_tb(); reg [1:0] test_in0, test_in1; wire test_out; integer log_file, console_file, out_file; reg [3:0] v_mem [0:7]; integer i; eq2 uu (test_in0, test_in1, test_out); initial begin log_file = $fopen("eqlog.txt"); if (!log_file) $display("Cannot open log file"); console_file=32'h0000_0001; out_file = log_file | console_file; $readmemb("vector.txt", v_mem); module eq2(input [1:0] a, b, output equal); assign equal = (a[0] ~^ b[0]) & (a[1] ~^ b[1]); endmodule

  38. Example, Contd. for (i=0; i<8; i=i+1) begin {test_in0, test_in1} = v_mem[i]; #200; end $fclose(log_file); $stop; end initial begin $fdisplay(out_file, " time test_in0 test_in1 test_out"); $fmonitor(out_file, "%10d %b %b %b", $time, test_in0, test_in1, test_out); end endmodule

  39. Example, Contd. • The vector.txt file stores the test patterns specified in 4-bit binary format. The content of the file is: • The simulated result is written to the console and the log file, eqlog.txt • The content of the log file is: 00_00 01_00 01_11 10_10 10_00 11_11 11_01 00_10 # time test_in0 test_in1 test_out # 0 00 00 1 # 200 01 00 0 # 400 01 11 0 # 600 10 10 1 # 800 10 00 0 # 1000 11 11 1 # 1200 11 01 0 # 1400 00 10 0

More Related