EmbDev.net

Forum: FPGA, VHDL & Verilog Serializer verilog


von Atalin (Guest)


Rate this post
0 useful
not useful
Hi! I am writing a code for a serializer. The problem is that I have 
only 1s as output but I want to see the input bitstream, obviously. Do 
you have any suggestion? Thanks.

The code is the following:
// Serializer

`timescale 1ns / 1ps

module serializer (data_in, send, clk, load, rst, data_out);

input wire [11:0] data_in;
input wire send, clk, load, rst;

output reg data_out;

reg [11:0] temp_data_out;
integer i;
integer j;

always @ (posedge clk) 
begin
  if (rst) begin
    data_out <= 1'b0;
    temp_data_out <= 12'b0;
  end
  else if (load)
    for(i=0; i<12; i=i+1)
      temp_data_out[i] <= data_in[i];
  else if (send)
    for(j=0; j<12; j=j+1)
      data_out <= temp_data_out[j];
    //data_out <= temp_data_out[0];
    //temp_data_out <= {temp_data_out[10:0], 1'b0};
end

endmodule //end module serializer

The testbench is
`include "serializer.v"
`timescale 1ns / 1ps

module serializer_tb();
// Declare inputs as regs and outputs as wires
reg [11:0] data_in;
reg send, clk, load, rst;
wire data_out;

// Initialize all variables
initial begin          
  clk = 1;       // initial value of clock
  rst = 1;       // initial value of reset
  load = 0;
  send = 0;
  data_in = 12'b110110110110;
  #15 rst = 0;   // De-assert the reset
  #13 load = 1;
  #15 load = 0;
  #5 send = 1;
  #125 send = 0;
  #10 data_in = 12'b100100010001;
  #10 load = 1;
  #15 load = 0;
  #5 send = 1;
  #125 send = 0;
end

// Clock generator
always begin
  #5 clk = ~clk; // Toggle clock every 5 ns - 100 MHz
end

// Connect DUT to test bench
serializer U_serializer (data_in, send, clk, load, rst, data_out);

endmodule

von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
Have a look what a for loop does in Verilog: it produces parallel 
hardware. It looks like you expect something entirely different.

BTW:
I assume this here:
    for(i=0; i<12; i=i+1)
      temp_data_out[i] <= data_in[i];
Could be cut down to one line:
      temp_data_out <= data_in;
But I may be completely wrong because I'm doing VHDL usually... ;-)

: Edited by Moderator
von Klakx (Guest)


Rate this post
0 useful
not useful
you toggle "load" at #13 and #15, but your clock toggles with #5 (and 
rising edges with 10). I think you will miss easily signals in that 
style

improve your testbench with:
@(posedge clk) 
load = 1;
@(posedge clk)
load = 0;

furthermore:
for(j=0; j<12; j=j+1)
      data_out <= temp_data_out[j];

// is the same like
      data_out <= temp_data_out[11];
In a N-serializer you have to use a 1-bit clock and your inputs stays at 
the correct time every N cycles or for N cycles.

von Atalin (Guest)


Rate this post
0 useful
not useful
Thank you! I tried to modify that line but nothig has changed...

von Atalin (Guest)


Rate this post
0 useful
not useful
Hi! For what concern the tesbench, in the simulation result I can see 
that when load is high, it returns to 0 after 15 ns. So, it is high for 
at least 1 clock cycle.

If I write
      data_out <= temp_data_out[11];

how I can see as output the whole bit stream? In this way I can see only 
temp_data_out[11] and not all the bits in that array

von VHDL hotline (Guest)


Rate this post
0 useful
not useful
Why you commented this line?
    //temp_data_out <= {temp_data_out[10:0], 1'b0};

This is basically what the serializer should do, shifting out the bits. 
Also, in hardware the for loops are unrolled and so all happens in one 
clock cycle and the last assignment wins. In your case, the second for 
loop always results to 'data_out <= temp_data_out[11]'. Discard the for 
loops and try like this:
always @ (posedge clk) 
begin
  if (rst) begin
    data_out <= 1'b0;
    temp_data_out <= 12'b0;
  end
  else if (load)
      temp_data_out <= data_in;  //take over the vector
  else if (send)
      data_out <= temp_data_out[11];  //assert the MSBit of the vector at output
      temp_data_out <= {temp_data_out[10:0], 1'b0}; //shift the vector by one bit per cycle
end

von Atalin (Guest)


Rate this post
0 useful
not useful
Yes you are absolutely righ, I commented that line because I was not 
sure (I am new in programming so maybe it is easier for me think with 
for loop..!) but I was thinking again about it and you confirmed my 
thought. Thank you very much!

von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
Atalin wrote:
> I am new in programming
Don't think you are "programming" like a software programmer writes a 
program for a computing device. What you are doing is "describing" 
hardware using a HDL (Hardware Description Language). So at first you 
must have a "picture" of that hardware on a sheet of paper or at least 
in your brain. Then you can describe it with Verilog (or VHDL or 
whatsoever).

By doing this don't let you betray by "false friends" like that 
"for-loop" in the posts above.

VHDL hotline wrote:
> This is basically what the serializer should do, shifting out the bits
But of course this serializer also could be done with a 12:1 
multiplexer. So with each clock a counter must count up and then this 
counter can be used for indexing the desired bit.

von Atalin (Guest)


Rate this post
0 useful
not useful
Hi guys! I am here again for asking some help. Here I have the testbench 
of the serializer (I slightly modify it in order to have random bits as 
input). I would like to add a kind of receiver (like a serial-in 
parallel-out register) in order to check automatically if the input 
parallel data are equal to the output. How can I do this? Thanks
`include "serializer.v"
`timescale 1ns / 1ps

module serializer_tb();
// Declare inputs as regs and outputs as wires
reg [11:0] data_in;
reg send, clk, load, rst;
wire data_out;


// Initialize all variables
initial begin          
  clk = 1;       // initial value of clock
  rst = 1;       // initial value of reset
  load = 0;
  send = 0;
  #15 rst = 0;   // De-assert the reset

  forever begin
    foreach(data_in[ii]) data_in[ii] = $urandom;
    #13 load = 1;
    #15 load = 0;
    #5 send = 1;
    #85 send = 0;
  end
end

// Clock generator
always begin
  #5 clk = ~clk; // Toggle clock every 5 ns - 100 MHz
end

// Connect DUT to test bench
serializer U_serializer (data_in, send, clk, load, rst, data_out);

endmodule

von Atalin (Guest)


Rate this post
0 useful
not useful
I find out this solution, maybe someone needs it too :)
 initial begin          
  clk = 1;       // initial value of clock
  rst = 1;       // initial value of reset
  load = 0;
  send = 0;
  #15 rst = 0;   // De-assert the reset

  forever begin
    foreach(data_in[j]) data_in[j] = $urandom;
    #13 load = 1;
    #15 load = 0;
    #5 send = 1;
    #20          //header
    for(i=0; i<12; i=i+1) begin
      #5 reg_sipo[11-i] <= data_out;
      end
    #5 send = 0;
    if(reg_sipo == data_in) check = 0;
    else check = 1;
  end
end 

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig