2016-10-06 1 views
0

이것은 Verilog HDL에서 처음 프로그래밍 한 것이며 코드에 무엇이 문제가 있는지 파악하는 데 어려움이 있습니다. 행동 코드에서 간단한 ALU를 디자인해야합니다.ALL 용 Verilog HDL behavioral coding 호출 모듈

지금까지는 감산기와 덧셈기 모듈을 만들었습니다. (모듈을 더 추가해야하지만 다른 모듈을 추가하기 전에 ALU 모듈에서이 모듈을 사용하고 싶습니다.)

나는 같은 프로젝트 (?이 행동입니다 확신) 별도의 .V 파일에 다음과 같은 모듈이 있습니다

module adder3bit(sum, co, a, b); 
parameter n = 2; 
output reg [n:0] sum; 
output reg co; 
input [n:0] a; 
input [n:0] b; 

always @(a, b) 
{co, sum} = a + b; 

endmodule 


module subtract3bit(diff, bo, a, b); 
parameter n = 2; 
output reg [n:0] diff; 
output reg bo; 
input [n:0] a; 
input [n:0] b; 

always @(a, b) 
{bo, diff} = a - b; 

endmodule 

나는이 테스트를하고 작업하는 것을 알 수있다.

module alu(out, overflow, a, b,sel); 
input [2:0] a, b; 
input sel; 
output [2:0] out; 
output overflow; 
always @(a,b,sel) 
begin 
if(sel=='b0) 
    adder3bit A1(out,overflow,a,b); 
if(sel=='b1) 
    subtract3bit S1(out, overflow, a, b); 
end 
endmodule 

내 구문이 잘못 될 수 있지만 오류를 보여주는 :

는 지금은 주요 ALU 모듈을 호출하는 것을 시도하고있다. 나는 Verilog에 익숙하지 않다. 나는 처음에 C를 배우면서 느낀 기분을 느낀다.

모듈을 올바르게 호출하고 있지만 if 문과 관련이 있다고 생각합니다.

고맙습니다. 새로운 것을 배우기를 바랍니다.

답변

2

처럼 될 것입니다. 모듈은 함수 또는 호출 할 수없는 작업이 아닙니다. 모듈로 할 수 있고해야할 일은 다른 모듈 (이 경우 ALU 모듈)에서 인스턴스화하는 것입니다. 모듈을 절차 블록 (코드에서 항상 e.x) 내부에서 인스턴스화 할 수 없습니다. 가산기와 감산기 모두 입력의 모든 변경에 대해 새로운 결과를 산출 할 것이므로이 모듈의 입력과 출력을 올바르게 읽는 것만으로 충분합니다.

I 조언 좀 더 읽기 쉬운 방식으로 모듈의 포트를 선언합니다 :

은 ALU에서
module adder3bit #(
    parameter N = 2 
) ( 
    output reg [N:0] sum, 
    output reg co, 
    input [N:0] a, 
    input [N:0] b 
); 
    always @(a, b) 
     {co, sum} = a + b; 

endmodule 

이 같은 adder3bit 인스턴스화 할 수 있습니다 :

module alu (
    input [2:0] a, 
    input [2:0] b, 
    input sel, 
    output [2:0] out, 
    output overflow 
) 
    localparam SIZE = 3; 
    wire [SIZE - 1 : 0] diff; 
    wire [SIZE - 1 : 0] sum; 
    wire co; 
    wire bo; 

    adder3bit #( 
     .N(SIZE) 
    ) adder (
     .a(a), 
     .b(b), 
     .sum(sum), 
     .co(co) 
    ); 

    subtract3bit #( 
     .N(SIZE) 
    ) subtractor (
     .a(a), 
     .b(b), 
     .diff(diff), 
     .bo(bo) 
    ); 

    always @(*) 
    begin 
     if(sel=='b0) 
      {out,overflow) = {sum, co}; 
     if(sel=='b1) 
      {out,overflow) = {diff, bo}; 
    end 
endmodule 

그리고 한 가지 더, 당신의 모듈은 매개 변수가있는 그것의 입력과 출력의 크기를 정의하지만 그것은 혼란 스러울 수있는 3 가지로 고정되어 있음을 암시합니다.

+1

'n'과 'N'을 사용하면 같은 매개 변수를 식별 할 수 있습니다. 둘 중 하나를 선택하십시오. 업계 및 여러 프로그래밍 언어의 일반적인 관행이므로 매개 변수를 식별하려면 대문자를 사용하는 것이 좋습니다 – Greg

+0

물론 맞습니다, 감사합니다! –

+0

도움 주셔서 감사합니다. 따라서 모듈을 미리 초기화해야합니다. 이것은 always 블록에있는 모듈의 출력을 읽을 때마다 a와 b에 따라 새로운 입력을 읽는 것을 의미합니다. 또한 두 개의 와이어 인 sum과 diff를 선언하는 대신 단일 출력 와이어를 사용할 수 있습니까? – Darklink9110

0

Verilog의 always 블록 안에 모듈을 인스턴스화 할 수 없습니다. 대신 adder3bit 및 subtract3bit 모듈을 작업으로 변경할 수 있으며 지금 작성한 코드를 사용할 수 있습니다. 솔루션은 주요 문제는 당신이 모듈을 호출 할 것입니다이

task adder3bit; 
parameter n = 2; 
input [n:0] a; 
input [n:0] b; 
output reg [n:0] sum; 
output reg co; 
begin 
always @(*) {co, sum} = a + b; 
endtask 


task subtract3bit; 
parameter n = 2; 
input [n:0] a; 
input [n:0] b; 
output reg [n:0] diff; 
output reg bo; 
begin 
always @(*) {bo, diff} = a - b; 
endtask 

module alu(out, overflow, a, b,sel); 
input [2:0] a, b; 
input sel; 
output [2:0] out; 
output overflow; 
always @(a,b,sel) 
begin 
if(sel=='b0) 
    adder3bit (a,b,out,overflow); 
if(sel=='b1) 
    subtract3bit (a,b,out,overflow); 
end 
endmodule 
+1

작업에는 '항상'블록을 포함 할 수 없으며'매개 변수 '를 선언 할 수 없습니다. – Greg

+0

항상 블록을 선언 할 수는 없지만 매개 변수를 사용할 수는 있습니다 ... –

+0

그 자체가 block_item_declaration의 하위 집합 인 구문 트리를 충분히 파고 들지 않았습니다.이 자체는 task에 의해 사용되는 tf_item_declaration의 하위 집합입니다. 그러나 LRM을 재검토하면서 _pure_ Verilog (IEEE 1364)가 모듈 외부에서 정의 된 작업/기능을 지원하지 않음을 알았습니다. SystemVerilog (IEEE 1800)에서는 유효합니다. 모든 최신 Verilog 시뮬레이터는 SystemVerilog 시뮬레이터이지만 컴파일러 플래그가 엄격한 Verilog로 설정된 경우 모듈 외부에서 정의 된 작업은 컴파일 오류 여야합니다. – Greg

관련 문제