Below is a synthesizable SystemVerilog snippet that demonstrates the SystemVerilog construct struct packed, that much like a struct in C allows a heterogeneous vector (e.g. a bunch of fields concatenated) to be accessed by individual field, or by the aggregate entity. In this class we will use the convention that all structs will end in _s.

Using structs can greatly simplify your code, so we present an exercise. The "course standards" version of Lab 2A employs these structs in a few places, and you should make sure that your code uses it appropriately for the rest of the class. It will greatly reduce code length and bugs.

A few tips:
  • logic is equivalent to a wire or reg.
  • '{ } is used to specify the fields of a struct.
  • . is used to access a field in the struct.
  • { } is used to group a bunch wires together, as presented before in class.
  • You are free to pull it in up in Quartus, try changing the code, etc. Or refer to this document, or the SystemVerilog standard, posted to the forum last week.
To complete this problem, you should turn the following items in via your zip file:
  • Draw the equivalent circuit, assuming that structs do not exist. Use the style that we set down for schematics in the last lab. e.g., Annotate signal widths, have left-to-right flow, etc. (Name this file your_name_struct_schematic.extension)

  • Annotate each section of the code with a description of what it does. You may use this as a reference (Section 5.3 talks about structs.) Since it is electronic submission, you may turn it in graphically (e.g. openoffice or powerpoint, in .pdf), or textually (e.g. comments on a .v file) (Name this file your_name_struct_annotation.extension)

  • Be thorough and don't stop until you understand every line -- although we grade it, this exercise is for you and not for us!
typedef struct packed {
 logic [17-1:0] instr;
 logic [10-1:0] addr;
} instr_packet_s;


module foo #(parameter A_WIDTH=10, I_WIDTH=17)
           (
             input clk
            ,input  [A_WIDTH-1:0] addr_i
            ,input  [I_WIDTH-1:0] instr_i
            ,output [A_WIDTH-1:0] addr_o
            ,output [I_WIDTH-1:0] instr_o
            );

instr_packet_s ip_n, ip_A_r, ip_B_r, ip_C_r;

assign ip_n = '{addr : addr_i
               , instr : instr_i };

assign { addr_o, instr_o }
 = {ip_C_r.addr, ip_C_r.instr };

always_ff @(posedge clk)
begin
  { ip_A_r, ip_B_r, ip_C_r } 
  <= { ip_n, ip_A_r, ip_B_r };
end

endmodule