Architecture 从头开始创建Verilog LZSS流水线体系结构
我正在用verilog为LZSS算法设计一个RTL。我在verilog中有一个用于此算法的工作代码。这个代码在Verilog中用C++风格编写。它运行起来,一切看起来都很好 现在我想提高这个算法的速度,我想把它流水线化。我有这个算法的详细流程图。现在看一下这个流程图,我可以决定这将在多少管道阶段结束。我在一个阶段能做多少组合逻辑有限制吗 请帮我制定一个逐步的流程,将此流程图转换为流水线verilog代码 提前谢谢 更新:源代码的副本Architecture 从头开始创建Verilog LZSS流水线体系结构,architecture,compression,verilog,register-transfer-level,Architecture,Compression,Verilog,Register Transfer Level,我正在用verilog为LZSS算法设计一个RTL。我在verilog中有一个用于此算法的工作代码。这个代码在Verilog中用C++风格编写。它运行起来,一切看起来都很好 现在我想提高这个算法的速度,我想把它流水线化。我有这个算法的详细流程图。现在看一下这个流程图,我可以决定这将在多少管道阶段结束。我在一个阶段能做多少组合逻辑有限制吗 请帮我制定一个逐步的流程,将此流程图转换为流水线verilog代码 提前谢谢 更新:源代码的副本 `时标1ns/10ps `定义EOF 32'HFFFF\U F
`时标1ns/10ps
`定义EOF 32'HFFFF\U FFFF
`定义成员大小200\u 000
`定义空0
//00 41 42 43 00 09 03 44 45 46 41 42 43
模块UnCompBF();
reg[80*8:1]填充名称;
reg[80*8:1]出料口名称;
参数EOF=-1;
整数填充、输出文件、内存索引、文件字符;
整数i,j,k,l;
整数公司;
注册[7:0]成员[4096:0];//我应该用多大尺寸??
注册[7:0]out_mem[4096:0];//我应该用多大尺寸??
reg[7:0]获取字符0,获取字符1;
reg[7:0]特殊字符;
reg[15:0]长度,偏移量;
首字母
开始:解压块
//将输入二进制文件加载到内存中
infilename=“comp_out.bin”;
infile=$fopen(infilename,“r”);
//检查输入文件是否已打开
如果(infle==`NULL)
开始
$display(“infle——文件未打开”);
禁用解压块;
结束
i=$fread(mem[0],infle);
$display(“加载了%0d个条目\n”,i);
$fclose(infle);
//打开输出文件进行写入
outfilename=“out0.txt”;
outfile=$fopen(outfilename,“w”);
$display(“加载到mem中的输入文件和打开的输出文件”);
//初始化
mem_indx=0;
文件\u char\u rd=0;
特殊字符=8'hxx;
j=0;
k=0;
$display(“初始化变量”);
//对于(j=0;j不幸的是,您实现此代码的方式似乎既不能合成到ASIC也不能合成到FPGA;整个过程只是一个大的初始块,并使用各种不可合成的系统调用
许多有编程经验但不熟悉HDL的人在理解设计HDL代码与软件代码的基本原则方面遇到了困难。在软件中,你给出了一组指令,这些指令将按顺序执行,然后由编译器转换为汇编指令。在HDL代码中,你是提供将由合成工具转换为门和非常基本的硬件组件的各种硬件组件的描述。在设计硬件时,最好尝试将系统构建为绘制电路图或RTL图(即使是在纸上进行也会很有帮助)组件可以并行运行,接收输入并驱动输出。您不是在调用函数,而是在实例化模块(更接近OOP,但仍然没有顺序元素)
在尝试实现如此复杂的东西之前,最好尝试更多地练习基础知识。网上有很多教程,但在深入学习RTL语言之前,最好先学习RTL设计的基础知识。再说一遍,Verilog是一种HDL,而不是编程语言,所以不要只是遇到教程作为学习语法的一种方式,你需要以一种全新的方式来学习,从基本逻辑和RTL设计开始,然后将设计转换成HDL代码
上面的代码和您对流程图的使用表明您有很强的编程背景,但在HDL中,您需要能够从RTL或电路图的角度来思考。希望这对您进入硬件世界有所帮助并祝您好运!您能添加您当前的代码吗?目标是什么:ASIC或FPGA(哪个)?每个阶段较长的组合逻辑会导致电路的目标频率较低。您好,osgx。感谢您的回复。这是代码。对不起,“这里”是代码?及其流程图,以及您的目标(FPGA名称和数据压缩/解压缩的目标速度)很抱歉,这是我关于stackoverflow的forst帖子,所以我想知道。他是一个快速链接,我也想做一个ASIC。如果你愿意,我也可以发布流程图。代码中的第一条注释行是//41 43..是这个程序的输入序列。
`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