从头开始创建Verilog LZSS流水线架构

时间:2014-04-03 06:49:32

标签: architecture compression verilog register-transfer-level

我正在为LZSS算法设计verilog RTL。我在verilog中有这个算法的工作代码。这段代码几乎是用verilog中的C ++风格编写的。它运行起来,看起来都很好。

现在我想提高这个算法的速度,我想管它。我有这个算法的详细流程图。现在看一下这个流程图我可以决定最终会有多少个流水线阶段。在一个阶段我可以做多少组合逻辑。

请帮我逐步制定流程图verilog代码。

提前致谢。

更新:http://collabedit.com/kvuu2

的源代码副本
`timescale 1ns / 10 ps
`define EOF 32'HFFFF_FFFF
`define MEM_SIZE 200_000
`define NULL 0

//00 41 42 43 00 09 03 44 45 46 41 42 43

module UnCompBF ();

  reg [80*8:1] infilename;
  reg [80*8:1] outfilename;

  parameter EOF = -1;
  integer infile, outfile, mem_indx, file_char_rd;
  integer i, j, k, l;
  integer inc_i;
  reg[7:0] mem [4096:0]; // what size should i use??
  reg[7:0] out_mem [4096:0]; // what size should i use??
  reg[7:0]  get_char0, get_char1;
  reg[7:0] special_char;
  reg[15:0] length, offset;

  initial   
    begin :  uncompress_block
        //Load input binary file into memory
        infilename = "comp_out.bin";
        infile = $fopen(infilename,"r");
        //Check if input file is opened
    if (infile == `NULL)
        begin
        $display("Infile  -- file not opening");
        disable uncompress_block;
        end 

    i = $fread(mem[0], infile);
    $display("Loaded %0d entries \n", i); 
    $fclose(infile);

    //Open output file for writing
    outfilename = "out0.txt";
    outfile = $fopen(outfilename,"w");
    $display("input file loaded into mem and output file opened");

    //Initialize 
    mem_indx = 0;
    file_char_rd = 0; 
    special_char = 8'hxx;
    j = 0;
    k = 0;
    $display("initialize variables");

    //for (j=0;j<i;j=j+1)
  while (j<i)
    begin
            $display("In while loop -- j=%d -- i=%d", j, i);
            inc_i = 0;
            if (j == 0)
                begin
                    special_char = mem[j];
                    inc_i = inc_i + 1;
                    $display("first byte is marker j %d inc_i %d marker %h", j, inc_i, special_char);  
                    // else if not first char and current char is equal to value of special_char
                end 
            else if ((j != 0) && (mem[j] == special_char))
                begin
                    $display("byte is equal to marker");
                    //get next char
                    get_char0 = mem[j+1];
                    inc_i = inc_i + 2;
                    // if next char is equal to 00
                    if (get_char0[7:0] == 8'h00) // Marker is 0 hence unmatched literal
                        begin
                            // special character is actually unmatched char 
                            // write previous into output fie
                            $fdisplay(outfile, "%2h ", mem[j]);
                            // write previous into memory
                            out_mem[k] = mem[j];
                            k = k + 1;
                            $display("length is 00 meaning marker part of output");
                            $display("mem[j] %h -- k %d", mem[j], k);
                        end
                    else // get length and offset of match string // Otherwise move forward to get the lenght                                and offset
                        begin
                            // get length of match string
                            if(get_char0[7] == 1)
                                begin
                                    //get next char
                                    get_char1 = mem[j+2];
                                    inc_i = inc_i + 1;
                                    length = {1'b0,get_char0[6:0],get_char1[7:0]};  
                                end 
                            else
                                length = {8'h00,get_char0[7:0]};                                        

                                $display("length is %h -- inc_i %d", length, inc_i);    
                                // get offset of match string
                                get_char0 = mem[j+inc_i];
                                inc_i = inc_i + 1;
                            if(get_char0[7] == 1)
                                begin
                                    //get next char
                                    get_char1 = mem[j+inc_i];
                                    inc_i = inc_i + 1;
                                    offset = {1'b0,get_char0[6:0],get_char1[7:0]};      
                                end 
                            else
                                offset = {8'h00,get_char0[7:0]};                

                                $display("offset is %h -- inc_i %d", offset, inc_i);    
                        end
                            // write out the string match in file and memory    
                            for( l = 0; l < length; l = l + 1 )
                                begin
                                    out_mem[k] = out_mem[ k - offset ];
                                    // write previous into output fie
                                    $fdisplay(outfile, "%2h ",  out_mem[k]);
                                    $display("using the length/offset pair");
                                    $display("out_mem adds %h -- k %d", out_mem[k], k);
                                    k = k +  1;
                                end
                    // else write unmatched char into file and memory   
            end 

                else 
                    begin
                        // write previous into output fie
                        $fdisplay(outfile, "%2h ",  mem[j]);
                        // write previous into memory
                        out_mem[k] = mem[j];
                        inc_i = inc_i + 1;
                        $display("output unmatched char");
                        $display("out_mem adds %h -- k %d", out_mem[k], k);
                        k = k + 1;
                    end
          j = j + inc_i;
          $display("j is %d", j);
    end
    $fclose(outfile);
  end
endmodule

1 个答案:

答案 0 :(得分:2)

不幸的是,您实现此代码的方式似乎无法合成到ASIC或FPGA;整个事情只是一个大的初始块,并使用各种不可合成的系统调用。

有许多具有编程经验但对HDL不熟悉的人有一件事就是理解设计HDL代码与软件代码的基本原则。在软件中,您提供了一组指令,这些指令按顺序执行,以便由编译器转换为汇编指令。在HDL代码中,您提供了由综合工具转换为门和非常基本的硬件组件的各种硬件组件的描述。在设计硬件时,最好尝试构建系统,就像绘制电路或RTL图表一样(即使在字面上在纸上进行也很有帮助)。组件可以并行运行,接收输入和驱动输出。你不是在调用函数,而是在实例化模块(更接近OOP,但仍然没有顺序元素)。

最好是在尝试实现这种复杂的东西之前,尝试使用基础知识进行更多练习。在线有很多教程,但在深入学习语言之前学习RTL设计的基础可能会更好。同样,Verilog是一种HDL,而不是一种编程语言,所以不要只是作为一种学习语法的方式进入教程。您需要以全新的方式处理它,从纸上的基本逻辑和RTL设计开始,然后将该设计转换为HDL代码。

上面的代码和您对流程图的使用表明您具有强大的编程背景,但在HDL中,您需要能够考虑RTL或电路图。希望这有助于进入硬件世界的好运!