本文共 3350 字,大约阅读时间需要 11 分钟。
1. VerilogmoduleC++classFullAdder module
module FullAdder(a, b, cin, sum, cout);
input a, b, cin;
output sum, cout;
assign {cout, sum} = a + b + cin;
endmodule
8-bitALU module8FullAdderALU8FullAdder
module ALU(a, b, result, cout, is_add);
input[7:0] a, b;
input is_add;
output[7:0] result;
output cout;
wire[7:0] b_not = ~b;
wire[7:0] b_in = is_add ? b : b_not;
wire[7:0] carry;
assign carry[0] = is_add ? 1'b0 : 1'b1;
// module
// 8-bit ripple adder
FullAdder fa0(a[0], b_in[0], carry[0], result[0], carry[1]);
FullAdder fa1(a[1], b_in[1], carry[1], result[1], carry[2]);
FullAdder fa2(a[2], b_in[2], carry[2], result[2], carry[3]);
FullAdder fa3(a[3], b_in[3], carry[3], result[3], carry[4]);
FullAdder fa4(a[4], b_in[4], carry[4], result[4], carry[5]);
FullAdder fa5(a[5], b_in[5], carry[5], result[5], carry[6]);
FullAdder fa6(a[6], b_in[6], carry[6], result[6], carry[7]);
FullAdder fa7(a[7], b_in[7], carry[7], result[7], cout);
endmodule
C++FullAdder classALU classFullAdderdata member
class FullAdder
{
};
class ALU
{
FullAdder fa[8];
};
另外一点,moudle声明port的方式,像是从早期C语言的函数定义中学来的:
char* strcpy(dst, src) char* dst; char* src;
{ // ...}另外一点,moudle声明port的方式,像是从早期C语言的函数定义中学来的:
char* strcpy(dst, src) char* dst; char* src;
{ // ...}2. VerilogC++memset()
void *memset(void *s, int c, size_t n);
如果你想将某个buf清零,应该这么写:
char buf[256];
memset(buf, 0, sizeof(buf));
但是如果你不小心写成了:
memset(buf, sizeof(buf), 0);
编译器不会报错,但运行的实际效果是根本没有对
buf
清零。(记得
Richard Stevens
VerilogALUmoduleALU
module alu_test;
reg[8:0] a_in, b_in;
reg op_in;
wire[7:0] result_out;
wire carry_out;
ALU alu0(.a(a_in[7:0]), .b(b_in[7:0]), .is_add(op_in),
.result(result_out), .cout(carry_out));
// ...
endmodule
这样就比较容易检查接线错误。
C++C++
3. Verilog{}bitbegin/endVerilog()[]C++Verilog<>bit{}
4. Verilogmoduletest benchtest fixturemoduletest benchVerilog(pair programming)ALU moduletest bench
`timescale 1ns / 1ns
module alu_test;
reg[8:0] a_in, b_in;
reg op_in;
wire[7:0] result_out;
wire carry_out;
ALU alu0(.a(a_in[7:0]), .b(b_in[7:0]), .is_add(op_in),
.result(result_out), .cout(carry_out));
reg[9:0] get, expected;
reg has_error;
initial begin
has_error = 1'b0;
op_in = 1'b1; // test addition
for (a_in = 9'b0; a_in != 256; a_in = a_in + 1)
for (b_in = 9'b0; b_in != 256; b_in = b_in + 1) begin
#1;
get = {carry_out, result_out};
expected = a_in + b_in;
if (get !== expected) begin
$display("a_in = %d, b_in = %d, expected %d, get %d",
a_in, b_in, expected, get);
has_error = 1'b1;
end
end
op_in = 1'b0; // test subtraction
// ...
if (has_error === 1'b0) begin
$display("ALL TESTS PASSED!");
end
$finish;
end
endmodule
5. VerilogVHDLconcrete classabstract classinterfaceimplementation
VHDLENTITYARCHITECTUREENTITYENTITYVHDLFreqDeviderBehaviorDataflow
LIBRARY IEEE;
USE IEEE.Std_Logic_1164.All;
ENTITY FreqDevider IS
PORT
( Clock : IN Std_Logic;
Clkout : OUT Std_Logic
);
END;
ARCHITECTURE Behavior OF FreqDevider IS
SIGNAL Clk : Std_Logic;
BEGIN
PROCESS (Clock)
BEGIN
IF rising_edge(Clock) THEN
Clk <= NOT Clk;
END IF;
END PROCESS;
Clkout <= Clk;
END;
ARCHITECTURE Dataflow OF FreqDevider IS
-- signal declarations
BEGIN
-- processes
END;
C++concrete classabstract classVerilogVHDL
6. VerilogVHDLVerilog(parameter)VHDL(generic)C++
7. Verilog是硬件描述语言,不是硬件设计语言。在用Verilog设计电路的时候,我们是把脑子中想好的电路用Verilog“描述”出来:哪里是寄存器、哪里是组合逻辑、数据通路是怎样、流水线如何运作等等都要在脑子里有清晰的映象。然后用RTL代码写出来,经过综合器综合出的电路与大脑中的设想相比八九不离十。这就像说CC
转载地址:http://vcaoi.baihongyu.com/