2016-08-29 7 views
0

장난감 프로세서 용 제어 논리 모듈을 작성하려고합니다. 그것은 페치/디코드/실행 상태를 순환하고, 다양한 메모리 비트로부터 읽고 쓰며, 제어 신호를 묶어줍니다. 다소 크기가 크며, 말할 것도없이 더 작은 모듈로 세분 될 수는 없습니다.큰 VHDL 모듈을 작성하고 읽을 수있게하려면 어떻게해야합니까?

모든 상태에 대한 논리를 하나의 프로세스에 넣고 싶지 않습니다. 읽기가 어렵고 중간 별칭 질량이 시뮬레이터를 사용할 때 고통스럽기 때문입니다.

각 상태의 논리를 자체 프로세스로 분할하려고했지만 여러 드라이버에 문제가있었습니다.

또한 하나의 주 프로세스의 헤드에서 각 상태의 논리에 대해 별도의 프로 시저를 선언하고 프로세스가 현재 상태를 기반으로 올바른 프로 시저를 호출했는지 확인했습니다. 이것은 모듈 형 "함수"와보다 읽기 쉬운 구조로 매우 잘 작동합니다 ... 그러나 각 프로 시저의 중간 신호는 시뮬레이터에서 볼 수 없습니다 (그리고 아마도 테스트 벤치에서 액세스 할 수 없을 수도 있습니다). 관련성이있는 경우 ISim을 사용하고있었습니다.

내가 잘못 했습니까? 하나의 막대한 모 놀리 식 프로세스를 피하기 위해 사용할 수있는 트릭이 있습니까?

EDIT : 모듈의 코드는 here입니다.

+0

추상 신호의 문제를 설명 할 위험이 있음을 입증하는 것은 변수를 나타낼 서브 프로그램 선언 항목 (IEEE Std 1076-2008, 4.3 서브 프로그램 본문)이 아닙니다 ("... 중간 신호는 명백한..."). [특정 프로그래밍 문제] (http://stackoverflow.com/help/on-topic)를 제공 할 수 있습니까? VHDL에서 하드웨어를 가장 잘 표현하는 방법은 세부 사항이나 설명이없는 경우에는 답할 수 없습니다. – user1155120

+0

귀하의 연결된 control.vhd 코드가 설명이 여러 주석의 허용 된 공간에 맞지 않는 이유로 작동하지 않습니다. 기능 코드를 제공한다면 가독성에 관한 문제의 종류가 크게 달라질 수 있습니다. 예를 들어, 상태에 대한 별도의 프로세스 대신 단일 프로세스에서 case 문을 사용해야합니다. 신호를 할당하는 각 프로세스에는 해당 신호의 드라이버가 있습니다. 해결 된 신호의 경우 확인 된 값이 유효 값입니다. is_uop은 is_call 및 is_direct처럼 항상 false입니다. – user1155120

답변

0

마찬가지로 귀하의 질문에 대답하기가 어렵습니다. 우리는 몇 줄의 이야기를하고 있습니까?

당신은 그래도 좋은 VHDL 코드 사례를 찾아 볼 수 있습니다 : - 별칭 (모든 도구도 다음 AFAIK를 지원) 피해야한다 - 변수에게 신호를/명확한 이름 을 제공 - 그룹 기능 시도 - 변경하지 않으려 고 2 개 장소의 신호/변수를 500 줄로 구분하면 일반적으로 VHDL93에 도입 된 공유 변수 사용을 고려해 볼 수 있습니다. - 정말 필요하다면. (이 뜻은, 그러나, 당신의 여러 드라이버 문제가 해결되지) - 그룹 신호 당신의 "중간 신호 표시"만들기에 대해

에 대한 기록의 가용성을 잊지 마세요, 당신이

junk_proc: process(clk, rst) is 
variable a,b,c: of_some_types; 
begin 
if rst then 
//do reset stuff 
elsif rising_edge(clk) 
b:=func1(a); 
c:=func2(b); 
end if; 
end process; 

변수를 작성할 수 , b 및 c (이 경우 일반 전선)는 분명히 모든 시뮬레이션 도구에서 시각화 될 수 있습니다.

그러나 b = func1 (func2 (func3 (func4 (a))))))를 작성하는 경우이 모든 것이 단일 클록 사이클에서 발생한다고 설명하는 것을 잊지 마십시오. 당신의 설명을 고려해 볼 때, 문제가 생길지 모르지만, 아마도 그것은 좋은 학습 방법입니다.

1

큰 VHDL 파일을 읽는 데 더 적합한 편집기를 사용해야 할 수도 있습니다. 나는 공간의 대부분이 단일 프로세스의 논리 인 3000+ 라인 VHDL 파일을 정기적으로 사용하며 코드 폴딩을 지원하는 편집기로 인해 읽는 데 어려움이 없습니다.

메모장 ++를 사용하지만 VHDL 구문에서 폴딩을 지원할 수있는 다른 편집기가 있다고 확신합니다. 파일을 열 때 Alt + 0을 눌러 가능한 모든 구문 폴딩 포인트를 접은 다음 필요에 따라 작업중인 파트로 확장합니다. 또한 라인 숨기기를 사용하여 파일의 임의 섹션을 접을 수 있습니다. 단점은 좀 더 어색한 작업입니다.

관련 항목이 많은 경우에는 name : if true generate으로 폴딩 포인트로 쉽게 그룹화 할 수 있으며 기본 아키텍처의 범위를 벗어나는 중간 신호를 선언 할 수도 있습니다 (block 문은 작동하지만 실제로는 작동하지 않습니다). 모든 도구에서 지원됨). 프로세스 내에서 접는 점을 강제로 사용하려면 if true then을 사용합니다.

+0

IEEE Std 1076-2008 14.5.3 문 생성 "생성 문을 정교화하려면 generate 문을 선언문이 generate 문 내에 포함 된 선언 항목으로 구성되고 block 문이 0 개 이상의 복사본으로 대체됩니다 generate 문 내에 포함 된 동시 문으로 구성됩니다. " 또한 11.8 문장을 생성하십시오. 블록 헤더 (포트, 제네릭, 맵)는 IEEE Std 1076.6-2004 8.9.1 (철회)에서 지원할 필요가 없습니다. 생성 문은 블록 헤더를 허용하지 않습니다. XST가 일치합니다. – user1155120

+0

블록 구문을 한 번 사용해 보았습니다. 나는 신디사이저 또는 시뮬레이터가 숨 막히지 않았던 지 기억하지 못한다. 공식 사양이 무엇을 말하는지에 관계없이 모든 것이 작동하도록 생성해야만했다. – QuantumRipple

1

거대한 case 문에서 다른 연산을 구현하는 프로세서를 설계한다면 실제로 설명하는 것은 출력 멀티플렉서에 공급하는 일련의 병렬 기능 유닛입니다. op 모드에 따라 곱셈, 더하기, 빼기, 일부 논리 연산, 시프트 등의 결과에 따라 출력이 발생할 수 있습니다.

모듈 형으로 쉽게 디자인 할 수 있습니다. 각 기능 단위를 자체 엔티티에 구현함으로써 일부는 매우 간단 할 수 있습니다. 첫 번째 예에서 이러한 블록은 무조건적으로 작동하고 출력은 출력 멀티플렉서에 공급됩니다. 나중에 명령 디코딩 로직에 의해 구동되는 인 에이블 신호를 추가하여 전원을 절약하기 위해 특정 작업에서 사용되는 블록 만 활성화 할 수 있습니다. 이 접근법을 사용하면 많은 제어 신호로 끝날 것 같지만 레코드에 모두 넣으면 코드가 아주 작아집니다. 동시에 제어 도구가있는 지점에서 자세한 정보와 가독성을 허용합니다 신호는 예를 들어, 사용됩니다

AddSub : entity work.AdderSubtractor 
port map (
    clk => clk, 
    enable => decoded_instruction.addsub_enable, 
    a => a, 
    b => b, 
    mode => decoded_instruction.addsub_mode, -- This might be an enumerated type 
    output => addsub_output 
); 

이 다른 _output 신호 것, 그리고 마지막에 당신이 이런 식으로 일을

OutputMux : process (all) 
begin 
    case decoded_instruction.output_mux_select is 
    when ADD_SUB => output <= addsub_output; 
    when MULT => output <= mult_output; 
    when LOGIC => output <= logic_output; 
    end case; 
end process; 

한 보너스 같은 당신이 그것을 찾을 수 있다는 것입니다있을 것입니다 FPGA의 DSP 블록에 구현 된 몇 가지 기능에 대해 효율적이다. 뺄셈, 곱셈, 쓰기를위한 기능 블록을 쉽게 설계 할 수 있으므로 디바이스의 DSP 블록을 타깃으로 할 수 있습니다. 이 출력은 '출력'멀티플렉서의 또 다른 입력이됩니다. 내 경험상 단일 DSP 블록 (또는 데이터 경로 너비에 따라 몇 개의 계단식 DSP 블록을 설명하는 단일 개체)을 사용하여 많은 처리 기능을 효율적으로 구현할 수 있어야합니다.

개인적으로 나는이 설계를 매우 모듈화하는 방식을 선호합니다. 최근의 멀티 코어 DSP 프로젝트에서는 대다수가 200 개 이하인 500 개 라인의 파일 만 있습니다. 즉, 디자인의 일부로 돌아 왔을 때 일반적으로 한 페이지에 들어가며 매우 짧은 시간 안에 쉽게 이해하고 이해할 수 있습니다. 또한 디자인의 성능을 향상시키기 위해 무거운 파이프 라이닝을 구현할 때 하나의 프로세스 또는 엔티티에서 너무 많은 작업을 수행하면이 작업의 규모가 더 커질 수 있습니다.

마지막으로, 기능 요소가 소규모 엔티티에 포함되어있는 경우 코드를 분리하여 시뮬레이션, 테스트 및 검증 할 수 있습니다. 내 경험상 블록을 더 빨리 승인 할 수 있습니다. 동시에 코드에 더 많은 자신감을 부여합니다. 모든 것이 하나의 과정에 있다면, 한 가지를 고치거나 개선하는 변화를 만들거나 다른 것을 깨뜨리지 않을 것이라는 확신을 갖는 것이 더 어렵습니다. 다시 한 번 심한 파이프 라인 디자인에서 우연히 설계가 공격적인 타이밍 제약 조건을 충족시키지 못하게 변경하는 것은 매우 쉽다는 것을 알았습니다. 따라서 엔티티가 단순할수록 이러한 일이 발생할 기회는 줄어 듭니다.

+0

한 단계 높은 수준으로 생각하고 있었지만 답변은 여전히 ​​유용하고 적절합니다 (현재와 이후 모두). 내 fetch/decode/execute 단계도 병렬 기능 단위라고 가정합니다. 다중 신호 드라이버의 문제점은 단일 프로세스에 스테이지를 넣음으로써 수정되었으며, 이것은 암묵적인 mux를 배경으로 보았습니다. 내가 올바른 스테이지에서 제어 신호를 수동으로 멀티플렉싱하면 별도의 프로세스로 돌아갈 수 있어야합니다. – FusterCluck