2017-01-16 4 views
2

항상 블록 내에서 다른 모듈의 출력을 사용하고 싶습니다. 현재이 코드를 작동시키는 유일한 방법은 pi_in 지정 뒤에 # 1을 추가하여 Pi가 완료 될 수있는 충분한 시간이 경과했는지 확인하는 것입니다. 모듈 pLayer.v에서Verilog : 항상 블록에서 모듈 논리 평가 대기

주요부 :

Pi pi(pi_in,pi_out); 

always @(*) 
begin 

    for(i=0; i<constants.nSBox; i++) begin 
     for(j=0; j<8; j++) begin 
      x    = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1; 
      pi_in   = 8*i+j;#1; /* wait for pi to finish */ 
      PermutedBitNo = pi_out; 
      y    = PermutedBitNo>>3; 

      tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y); 
     end 
    end 
    state_out = tmp; 
end 

Modllue Pi.v

`include "constants.v" 

module Pi(in, out); 
input [31:0] in; 
output [31:0] out; 
reg [31:0] out; 

always @* begin 
    if (in != constants.nBits-1) begin 
     out = (in*constants.nBits/4)%(constants.nBits-1); 
    end else begin 
     out = constants.nBits-1; 
    end 
end 
endmodule 

지연 때문에 # 1을 사용하지 않고 다른 방법이 최종 구현에 사용되어서는 안된다 ?

사실상 PermittedBitNo = pi_out은 Pi 모듈이 pi_in (= 8 * i + j)을 입력으로 사용하여 작업을 마친 후에 만 ​​평가되기를 원합니다. Pi가 완료 될 때까지 어떻게이 선을 차단할 수 있습니까?

시계를 사용해야합니까? 그렇다면 힌트를주세요.

업데이트 : 내 모듈을 수정 Krouitch 제안을 바탕으로

. pLayer.v에서

: Pi.v에서

Pi pi(.clk (clk), 
     .rst (rst), 
     .in (pi_in), 
     .out (pi_out)); 

counter c_i (clk, rst, stp_i, lmt_i, i); 
counter c_j (clk, rst, stp_j, lmt_j, j); 

always @(posedge clk) 
begin 
    if (rst) begin 
     state_out = 0; 
    end else begin 
     if (c_j.count == lmt_j) begin 
      stp_i = 1; 
     end else begin 
      stp_i = 0; 
     end 

     // here, the logic starts 
     x    = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1; 
     pi_in   = 8*i+j; 
     PermutedBitNo = pi_out; 
     y    = PermutedBitNo>>3; 
     tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y); 

     // at end 
     if (i == lmt_i-1) 
      if (j == lmt_j) begin 
       state_out = tmp; 
      end 
    end 
end 
endmodule 

module counter(
    input wire clk, 
    input wire rst, 
    input wire stp, 
    input wire [32:0] lmt, 
    output reg [32:0] count 
); 

[email protected](posedge clk or posedge rst) 
    if(rst) 
     count <= 0; 
    else if (count >= lmt) 
     count <= 0; 
    else if (stp) 
     count <= count + 1; 
endmodule 

: 여기에 업데이트 된 버전 당신이 여기있는 소프트웨어의 좋은 조각의

always @* begin 
    if (rst == 1'b1) begin 
     out_comb = 0; 
    end 
    if (in != constants.nBits-1) begin 
     out_comb = (in*constants.nBits/4)%(constants.nBits-1); 
    end else begin 
     out_comb = constants.nBits-1; 
    end 
end 

[email protected](posedge clk) begin 
    if (rst) 
     out <= 0; 
    else 
     out <= out_comb; 
end 

답변

3

은 ...

이 언어가 하드웨어를 설명한다는 사실은 도움이되지 못합니다.

Verilog에서 작성한 내용은 제로 시간에 시뮬레이션됩니다. ij에 대한 루프가 0 시간 내에 완전히 완료됨을 의미합니다. 루프가 #1으로 1 시간 단위로 대기하도록 할 때 뭔가를 볼 수 있습니다.

예, 시계을 사용해야합니다.

시스템을 작동 시키려면 ij에 대한 카운터를 구현해야합니다. 리셋

카운터 동기식 카운터는 다음과 같이 쓸 수있다 : 당신은 당신이 pi_in이 처리 될 경우에만 pi_out을 샘플링하도록 지정

`define SIZE 10 
module counter(
    input wire clk, 
    input wire rst_n, 
    output reg [`SIZE-1:0] count 
); 

[email protected](posedge clk or negedge rst_n) 
    if(~rst_n) 
    count <= `SIZE'd0; 
    else 
    count <= count + `SIZE'd1; 
endmodule 

. 디지털 디자인에서는 pi_in을 보내는 순간과 pi_out을 읽는 순간 사이에 1 클럭주기를 기다리고 싶다는 의미입니다.

내 생각에 가장 좋은 해결책은 pi 모듈을 순차적으로 만들어서 pi_out을 등록자로 간주하는 것입니다.

  1. 을 새로운 시계 : 이것은 무슨 일이 일어날 지 당신이 ij이 지난 pi 모듈에 대한 카운터를 사용하는 경우

    module Pi(in, out); 
    input   clk; 
    input [31:0] in; 
    output [31:0] out; 
    reg [31:0] out; 
    wire  clk; 
    wire [31:0] out_comb; 
    always @* begin 
        if (in != constants.nBits-1) begin 
        out_comb = (in*constants.nBits/4)%(constants.nBits-1); 
        end else begin 
        out_comb = constants.nBits-1; 
        end 
    end 
    
    [email protected](posedge clk) 
        out <= out_comb; 
    
    endmodule 
    

    빨리 :

    내가 다음을 수행 할 것을해야 할 일 사이클, ij이 변경됨 ->pi_in가 동시에 (시뮬레이션에서) 동시에 변경됨
  2. 다음 cl에 옥토퍼스주기 out_combout에 저장됩니다 한 다음 pi_in

EDIT 모든

첫째보다 한 클럭 사이클 나중에 pi_out의 새로운 값을 갖게됩니다, 쓰기 (동기) 프로세스, 나는 것 프로세스별로 1 개의 등록 정보 만 처리하도록 조언하십시오. 코드를보다 명확하고 이해하기 쉽고 디버그 할 수 있습니다.

또 다른 팁은 조합 회로를 순차적으로 분리하는 것입니다. 또한 코드를 명확하고 이해하기 쉽게 만듭니다.

내가 이전에 쓴 카운터의 예를 취할 경우처럼 보일 것 : 여기 당신이 예상보다 하나 더주기를 왜 내가 볼

`define SIZE 10 
module counter(
    input wire clk, 
    input wire rst_n, 
    output reg [`SIZE-1:0] count 
); 

//Two way to do the combinatorial function 
//First one 
wire [`SIZE-1:0] count_next; 
assign count_next = count + `SIZE'd1; 

//Second one 
reg [`SIZE-1:0] count_next; 
[email protected]* 
    count_next = count + `SIZE'1d1; 


[email protected](posedge clk or negedge rst_n) 
    if(~rst_n) 
    count <= `SIZE'd0; 
    else 
    count <= count_next; 


endmodule 

당신이 제어하는 ​​조합 회로를 넣어 때문에, 그것은 당신의 pi 모듈이 동기화 프로세스에 있습니다. , pi_out가 그래서

을 포착되는 pi_in

  • 다음 사이클을 평가,

    1. clk 양의 에지 ij
    2. 다음 사이클을 평가한다 : 그것은 다음과 같은 일이 일어날 것을 의미한다 2 사이클이 걸리는 것은 당연합니다.

      동기식 프로세스에서 '논리'부분을 제거해야한다는 것을 수정하십시오. 논평에 언급했듯이 그것은 논리이기 때문에 동기 과정에 있어서는 안됩니다.

      희망 하시겠습니까?

  • +0

    감사합니다. 그러나 지금은 out_comb가 항상 하나가 아니지만 (어떤 이유로) 2 사이클 후에 문제가 발생합니다. 그래서 내가 tmp에서 PermuteBitNo를 사용할 때 잘못된 결과를 반환합니다. – cie

    +0

    게시물을 추가 할 수 있습니까? – Krouitch

    +0

    out_comb는 항상 블록에 할당되어 있기 때문에 reg 여야합니다. 또한 왜 네가 무효화 재설정을 사용했는지 모르겠습니다. 구체적인 이유가 있습니까? – cie