HDLBits – Module shift8

This exercise is an extension of module_shift. Instead of module ports being only single pins, we now have modules with vectors as ports, to which you will attach wire vectors instead of plain wires. Like everywhere else in Verilog, the vector length of the port does not have to match the wire connecting to it, but this will cause zero-padding or trucation of the vector. This exercise does not use connections with mismatched vector lengths.

You are given a module my_dff8 with two inputs and one output (that implements a set of 8 D flip-flops). Instantiate three of them, then chain them together to make a 8-bit wide shift register of length 3. In addition, create a 4-to-1 multiplexer (not provided) that chooses what to output depending on sel[1:0]: The value at the input d, after the first, after the second, or after the third D flip-flop. (Essentially, sel selects how many cycles to delay the input, from zero to three clock cycles.)

The module provided to you is: module my_dff8 ( input clk, input [7:0] d, output [7:0] q );

The multiplexer is not provided. One possible way to write one is inside an always block with a case statement inside. (See also: mux9to1v). See the HDLBits page for a diagram.

Note: In modern SystemVerilog, the always keyword should not be used. Instead, always_ff will be used for sequential logic and always_comb will be used for combinational logic.

https://hdlbits.01xz.net/wiki/Module_shift8

This exercise is basically the same as the last one, but with the addition of an 8-bit wide 4-to-1 multiplexer. Although it’s mentioned on the HDLBits website, we will not use the always(*) pattern to create combinational logic in modern SystemVerilog. Instead, we will use the always_comb keyword. In line with this improvement, you should never be using the always keyword in new code. However, you should still know how it works since it will show up in generated IP (like from Vivado) and legacy code.

We could optimize this solution to reduce the lines of code, but I feel that the design intent is crystal clear and easy to modify (at the cost of some additional lines of code).

module top_module ( 
  input  logic clk, 
  input  logic [7:0] d, 
  input  logic [1:0] sel, 
  output logic [7:0] q );
  // Define internal logic
  logic [7:0] q0, q1, q2;
  
  // Module instantiations
  my_dff8 dff0_i (
    .clk(clk),
    .d(d),
    .q(q0) );
    
  my_dff8 dff1_i (
    .clk(clk),
    .d(q0),
    .q(q1) );
  my_dff8 dff2_i (
    .clk(clk),
    .d(q1),
    .q(q2) );
  // 8-bit wide, 4-to-1 multiplexer
  always_comb begin
    case (sel)
      2'b00   : q =  d;
      2'b01   : q = q0;
      2'b10   : q = q1;
      2'b11   : q = q2;
      default : q = '0; 
    endcase
  end
endmodule : top_module

Leave a Reply

Your email address will not be published. Required fields are marked *