VHDL 인터뷰 질문-나머지없이 숫자를 5로 나눌 수 있는지 감지


24

VHDL에 대한 멋진 인터뷰 질문을 보았습니다. 번호를 받고 나머지없이 5로 나눌 수 있는지 감지하는 시스템을 구축하십시오. 나는 상태 머신으로 그것을 해결하려고 노력했다. (나는 그들이 당신이 mod 또는 rem 을 사용하고 싶지 않다고 가정한다 ) 초기 성공 (5, 10, 15와 같은 숫자와 20, 40, 80과 같은 숫자는 성공했다) ), 130, 75 등과 같은 다른 숫자는 실패했습니다.

나는 내 상태 머신을 보여줄 것이지만 완전한 엉망입니다 (코드가 아니며 그림입니다). 내가 말했듯이 작동하지 않습니다.

기본적으로 내가 시도한 것은 5로 나눌 수있는 이진수로 기록하고 그에 적합한 상태 머신을 작성하는 것입니다.

이 문제를 해결하는 방법과 이와 같은 문제에 직면했을 때 생각하는 방법을 보여 주시면 기쁩니다.

고맙습니다!


정수 리터럴을 5로 나눌 수 있는지 테스트하는 코드뿐만 아니라 (합성 가능한) 하드웨어 구현을 의미합니다 (예 : 테스트 벤치).
smci

@smci 나는 실제로 상태 머신의 회로도 / 도면을 요구했지만 그 상태 머신의 코드는 아프지 않을 것입니다. Dave Tweed는 질문에 완벽하게 대답했습니다.
Eran

* "VHDL 인터뷰 질문
-cct

egreg math.stackexchange.com/a/2569882/213607에 의해 여기에 대답 하면 더 평행 한 접근 방식에 대한 영감을 줄 수 있습니다.
mathreadler

답변:


37

직렬 방식으로 나머지 작업을 수행하는 것은 실제로 매우 쉽습니다. 중요한 가정은 데이터가 직렬 인 경우 MSB 우선으로 제공된다는 것입니다. 나머지 모듈러스 N을 계산하려면 N 상태 만 필요합니다. "0"상태에서 시작하고 마지막 비트 이후에 "0"상태가되면 (비트 수는 중요하지 않음) 나머지는 제로.

개략도

이 회로 시뮬레이션CircuitLab을 사용하여 작성된 회로도

추적해야 할 유일한 것이 남은 부분이라면 어떻게 긴 분할을 할 것인지 생각하십시오.

process (clk)
begin
  if rising_edge(clk) then
    if reset = 1 then
      state <= 0;
    else
      if (state & din) >= N then
        state <= (state & din) - N;
      else
        state <= state & din;
      end if;
    end if;
  end if;
end process;

6
와우, 나는 그것이 작동하는 것을 보았지만 상태 머신을 어떻게 생각해 냈는지 설명 할 수 있습니까? 출발점이 무엇입니까? 나는 이것이 논리를 이해하는 방법에 대해 궁금한가요?
zoder

7
상태 다이어그램은 N = 5의 특정 사례에 대한 VHDL 코드에서 얻은 것입니다. 즉, 상태가 현재 나머지를 나타내는 경우 다음 상태는 상태를 한 비트 왼쪽으로 이동하고 입력 비트를 추가 한 다음 필요한 경우 5를 뺍니다.
Dave Tweed

3
이것은 아름답다면 누군가가 인터뷰에서 스스로 생각해 내면 정말 감동받을 것입니다. 그런 다음, 매 클록주기마다 전체 벡터를 처리하기 위해 rem 연산자를 사용하는 것과 비교하여 합성 결과가 어떻게 다른지에 대해 의견을 보내주십시오.
Casperrw

8
@ 조더 상태는 잔기 mod 5이고; 0 화살표는을 가리키고 2n mod 51 화살표는을 가리 킵니다 (2n + 1) mod 5.
hobbs December

2
당신의 선언을 추가 할 수 있습니다 state, dinN코드에?
mkrieger1

15

데이터가 LSB 우선 인 경우 상태 머신을 설계 할 수도 있습니다.

A graphic representation of the DFA as described at the end of this answer in the appendix.

이러한 결정 론적 유한 오토 마톤 (DFA) 의 존재는 MSB-first에 대한 DFA를 설명하는 다른 답변 에서 직접 이어진다. DFA에서 허용되는 언어는 일반 언어이며 일반 언어는 반전시 닫히는 것으로 알려져 있으므로 (예 : 여기 참조 ) 다음 언어를 허용하는 DFA가 있어야합니다.

있습니다.L={w{0,1}| reverse(w)10 is divisible by 5}

구성

  1. Dave Tweed의 답변 에서 MSB 최초의 DFA를 복사합니다 . 나는 자동 도구 JFLAP 를 사용했습니다.

  2. CS.SE : DFA 디자인 및 그 반대에 설명 된대로 DFA 리버설에 대한 명시 적 변환 알고리즘을 적용합니다 . 이 답변
    이전 개정판 에서이 단계의 (최소화되지 않은) 결과를 볼 수 있습니다 .

  3. 결과 DFA를 최소화하십시오. 불행히도이 기능은 최신 JFLAP 버전에서 약간 버그가 있으므로 직접 최소화했습니다.
    다시 말하지만, 거기에는 많은 알고리즘과 소스가 있습니다 . tutorialspoint.com의“DFA 최소화”에 설명 된 알고리즘을 사용했습니다 .

    (실제로 DFA를 살펴보면서 눈이 충분히 훈련을 받았다면 q 2 와 2에서 얻은 것과 같이 q 0q 1 이 DFA에서 동등한 상태 라는 것을 직접 수 있습니다 . !)q0q1

실제로, 결과 오토 마톤은 올바른 답변을 제공합니다.

Table with two columns "Input" and "Result" listing whether various number results in "Accept" or "Reject".


Arev5=(Q,Σ,δ,q0,F)Q={q0,q1,q2,q3,q4}Σ={0,1}F={q0}δ

δ(q0,0)=q0,δ(q0,1)=q1δ(q1,0)=q4,δ(q1,1)=q3δ(q2,0)=q1,δ(q2,1)=q2δ(q3,0)=q2,δ(q3,1)=q4δ(q4,0)=q3,δ(q4,1)=q0


DFA를 되 돌리는 데 어려움이 있다면 방정식을 뒤집을 수도 있습니다. new_state = state * 2 + input 대신 (new_state-input) / 2 = state를 사용한 다음 state와 new_state를 바꿀 수 있습니다. 새로운 방정식에 대한 DFA는 LSB- 첫 번째 문제를 해결해야합니다.
Eyal

Q3 및 Q4에 왜 그렇게 레이블이 지정되지 않은가? 라벨 q3과 q4를 바꾸면 기계는 algo를 "반 (mod 5)과 입력 비트 추가"를 구현합니다.
Rosie F

2
@RosieF : "반 (mod 5)"이라는 어구는 이산 수학에 익숙하지 않은 사람들을 위해 더 많은 설명을 사용할 수 있습니다. 이 문맥에서 나눗셈은 숫자를 균등하게 나누기 위해 필요한 배수의 배수를 추가하는 것을 수반하므로 3/2 (mod 5)는 (3 + 5) / 2, 즉 4가됩니다.
supercat

7

(MSB first) 상태 머신을 만드는 한 가지 방법은 다음과 같습니다.

  1. 지금까지받은 번호는 N입니다. 나머지를 알고 있다고 가정합니다 M = N mod 5.

  2. 새로운 비트가 등장하고 새로운 가치가 지금 N' = N*2 + b있습니다.

  3. 그러면 새로운 나머지가 M' = (N*2 + b) mod 5 = (M*2 + b) mod 5있습니다.

이것은 손으로 직접 표를 작성하기에 충분히 쉽습니다.

    남 b | 엠'
------------------
    0 0 | 0
    1 0 | 2
    2 0 | 4
    3 0 | 1
    4 0 | 삼
    0 1 | 1
    1 1 | 삼
    2 1 | 0
    3 1 | 2
    4 1 | 4

Dave Tweed의 답변에있는 상태 시스템과 일치합니다.


5

인터뷰 질문에 VHDL이나 Verilog의 기능보다는 문제를 어떻게 해결할 것인지에 대한 질문이 있었기를 바랍니다. 알고리즘이 있으면 언어 세부 사항이 간단합니다.

S=0S(2S+d) mod 5 SS,dS=0,,4

S=0,k=0S(S+2kd) mod 5,kk+1k24=1 mod 5S(S+2kd) mod 5,k(k+1) mod 4S,k,d(S,k)S=0,,4k=0,,3


3

VHDL을 작성하는 대상에 따라 VHDL을 직접적인 조합 계산으로 설명하는 접근 방식을 원할 수 있습니다. 숫자를 수신한다는 것은 전체 숫자가 한 클럭주기 동안 레지스터에 있음을 의미 할 수 있습니다.

예를 들어, 각 비트가 나타내는 값의 mod 5를 기록하고 이들을 함께 더한 다음 5보다 작은 값이 남을 때까지 프로세스를 반복 할 수 있습니다. 또는 적은 수의 사이클에 대해 로직을 재사용하십시오.

그러나 VHDL rem 연산자를 사용하면 정답 일 수 있습니다. 회사에 적절한 합성 도구가 있다고 가정하면 상태 머신 솔루션보다 약간 더 넓은 영역이지만 전체 처리량과 계산 당 좋은 에너지가 될 것입니다. 구현하는 데 가장 적은 시간이 걸리므로 고용주에게 가장 적은 비용이 드는 옵션입니다!

공평하게 말하면 아마도 그러한 질문에 대한 답이 아닐 수도 있지만 실제 디자인 경험을 과시 할 수있는 기회이기도합니다.


3

숫자가 1 비트보다 큰 청크로 표시되는 경우, 일부 병렬 계산을 사용하여 잔차 모드 15를 계산하는 것이 도움이 될 수 있습니다. 단, 잔차가 0이면 계산 15를 산출 할 수 있습니다. mod-15 잔류 물을 계산하는 간단한 방법은 N> = 1의 모든 값에 대해 그 이상의 숫자 부분에 가장 왼쪽의 4N 비트를 추가하면 원래의 mod 15와 일치하는 값이 생성됨을 관찰하는 것입니다. 사용 가능한 리소스에 따라 여러 가지 방법으로 문제를 세분화 할 수 있습니다.

예를 들어, 32 비트 값으로 시작하면 8 개의 4 비트 값으로 처리 될 수 있습니다. 그것들은 쌍으로 더해 4 개의 5 비트 값을 생성 할 수 있으며, 2 개의 6 비트 값 또는 1 개의 7 비트 값으로 결합 될 수 있습니다. 7 비트 값의 상위 3 비트를 하위 4 비트에 추가하면 최대 21 비트 인 5 비트 값이 생성됩니다. 따라서 최종 값이 0인지 여부를 관찰하여 원래 값이 5의 배수인지 여부를 확인할 수 있습니다. 0, 5, 10, 15 또는 20 중 하나입니다.


... 또는 전체에서 4 비트 가산기를 사용할 수 있으며 각 캐리 아웃이 나중에 회로의 가산기에 대한 캐리 인이되도록하십시오. 3 개의 레이어를 추가하면 하나의 4 비트 결과와 4 개의 아직 사용되지 않은 캐리가 있습니다. 마지막 4 비트 추가와 함께 3 개의 캐리를 함께 추가하고 마지막 캐리를 캐리 인으로 결과에 합계를 추가합니다. 이것은 최대 19를 산출하므로 나중에 20에 일치하지 않아도됩니다.
Henning Makholm

@HenningMakholm : 원하는 결과를 얻기 위해 가산기를 배열하는 방법에는 여러 가지가 있습니다. 주어진 상황에서 어떤 접근 방식이 더 좋을지는 프로젝트 별 라우팅 또는 리소스 활용 문제에 따라 달라질 수 있습니다. 또 다른 방법은 캐리-세이브 (carry-save) 가산기를 사용하는 것이지만, 시프트 된 출력의 최상위 비트가 하단으로 이동 될 수 있다는 사실을 이용하십시오. 따라서 한 계층은 8 개의 입력을 6으로, 6은 4로, 4는 3으로, 3은 2로 전환 할 수 있습니다. 각 계층의 한 출력은 단순히 AND 게이트와 다른 하나는 XOR 게이트가되므로 전파 시간은 ...에 대한 4 비트 값 쌍
supercat

... 하나의 운반 체인은 4 개의 xor 게이트의 체인 일 것입니다. 출력을 19 미만으로 얻는 것이 더 나은지 또는 가능한 잔류 물로 20을 확인하는 것이 더 좋은지에 대해서는 아마도 자원 가용성 및 활용에 달려 있습니다. 30보다 크지 않은 숫자가 주어지면 상단 및 하단 니블을 추가하면 최대 15 (16 + 14-> 1 + 14 또는 0 + 15-> 0 + 15)의 값을 얻을 수 있지만 명시 적을 추가합니다 (20, 25, 30)의 일부 또는 전부를 검사하는 것이 더 저렴할 수 있습니다.
supercat

2

내 VHDL을 기억할 수 없지만 다음은 처음 떠오른 아이디어에 대한 스케치입니다.

두 번째 거듭 제곱의 마지막 자릿수 (10 진수)는 1, 2, 4, 8, 6, 2, ...이며주기가 반복됩니다. 따라서 2의 거듭 제곱의 나머지 mod 5는 1, 2, 4, 3, ...입니다.

이를 사용하여 LSB에서 비트 단위로 이동하고 1비트가 보일 때마다 위치에 해당하는 나머지 mod 5를 누적 할 수 있습니다. 축적 모드 5도 수행하십시오. 끝에 합계가 0인지 확인하면 충분합니다.


1

우리는 여기의 답에서 아이디어 사용할 수 있습니다. 베이스 4에서는 교호 숫자 합계가 5 인 경우에만 숫자를 5로 나눌 수 있다는 것을 알 수 있습니다. 그러므로 우리는

  1. 숫자 2를 2로 묶고
  2. 홀수를 합산하고 짝수의 2 비트 블록을 뺍니다.
  3. 결과가 예를 들어 [-4,3]과 같이 몇 비트의 2 개의 보수 영역에있는 경우 (2 개의 보수를 사용한다고 가정하면 쉽게 확인할 수 있음) 완료되고 결과가 summation은 0으로 확인하는 매우 간단한 논리적 표현입니다 (기본적으로 크거나 모든 결과 비트에서 아니오)?
  4. 그렇지 않으면 우리는 새로운 것을 반복합니다 (훨씬 짧은 숫자).

숫자 166 = (10) (10) (01) (10)으로 시도해 봅시다 : 2,2,1,2

2-2 + 1-2 = -1

166이 5로 균등하게 나뉘 지 않는다는 단 한 번의 반복으로 결론을 내릴 수있는 이유는 절대 값이 <= 3이고 0이 아닙니다.

작은 메모리는 반복하는 것보다 게이트의 속도 / 수의 측면에서 저렴 / 더 좋을 수 있습니다. 물론 최악의 경우 (허용 된 입력에 따라 가능한 가장 큰 결과)를 미리 계산하고 그에 따라 설계를 계획 할 수 있습니다.


1

MSB 접근 방식은 확실히 쉽지만 MSB 솔루션을 생성하지 않고도 LSB 상태 다이어그램을 관리 할 수있었습니다. 몇 시간이 걸렸습니다. @ComFreek에 표시된 것과 동일하며 다르게 주석이 달렸습니다.

우리는 두 숫자를 추적 할 것입니다. 먼저, 누적 합계 모듈로 5 ( "SUM")를 추적하겠습니다. 둘째, 다음으로 거듭 제곱 할 다음 거듭 제곱 값인 모듈로 5 ( "NEXT")를 추적합니다. 상단에 "SUM"에 대한 가능한 값과 그 아래에 해당하는 "NEXT"값으로 각 상태를 표시하겠습니다.

"SUM"모듈로 5가 0 인 경우부터 시작하겠습니다.

머리 글자


3,2,4,1
1,4,3,2 와 같은 상태입니다.


1,3,4,2
2,1,3,4 와 같습니다.

두 상태 모두
SUM = 1 및 NEXT = 4 OR
SUM = 2 및 NEXT = 3 OR
SUM = 3 및 NEXT = 2 OR
SUM = 4 및 NEXT = 1을 나타냅니다.

이제 대부분의 면접관은 상태가 하나 인 상태 다이어그램에 감명을받지 않으므로 추가 상태를 개발해야합니다. 우리는 모든 주에 두 개의 전이가있을 때 완료됩니다.

새 상태로 전환 할 때마다 "NEXT"의 각 숫자가 두 배가되고 모듈로가 5가됩니다. "SUM"의 경우 다음 규칙을 따르십시오.

  • 0을 따라 전환하면 맨 위 행의 값이 유지됩니다.
  • 1을 따라 전환 한 경우 각 열은 이전 상태의 "SUM"+ "NEXT"모듈로 5입니다.

이제 들어오는 비트가 1 일 때 전환을 채우면서 시작하겠습니다.

모든 1

자 이제 우리는 0을 채 웁니다. 하나의 상태 만 추가되었으므로 계속 진행하여 전환을 채 웁니다.

완전한

그리고 짜잔! MSB 솔루션을 생성하지 않고도 LSB를 먼저 수락하는 상태 머신이 있습니다.


1

위의 모든 것이 너무 복잡해 보입니다! 이진 정수를 5로 나눌 수 있는지 여부를 감지하는 쉬운 수학 방법이 있습니다. 우선, 보통 십진 산술에서 "9를 캐스트"하는 방법을 기억하십니까? 십진 정수의 잔차 모듈로 9는 자릿수 합계의 잔차 모듈로 9와 동일합니다. 9는 숫자 기반보다 하나가 작기 때문에 작동합니다.

대체 숫자의 부호가 음수로 설정되어있는 "11을 캐스트"하는 유사한 프로세스가 있습니다. 11은 숫자 기반보다 1이 크기 때문에 작동합니다.

따라서 "5를 캐스트"하려면 정수 4를 정수로 나타낼 수 있습니다. 그런 다음 가장 낮은 숫자 쌍을 초기 합으로 시작하고 다음 숫자 쌍에서 빼서 다음 합을 얻습니다. 이 방법으로 후보 정수를 통과 한 후 원래 정수가 5로 나눌 수있는 경우 최종 합은 0 또는 5로 나눌 수 있습니다.

예 70 : 01 00 01 10-> 01 00 -1-> 01 01-> 00, 5로 나눌 수 있음 예 49 : 11 00 01-> 11-1-> 1 00-> 1, NOT 5로 나눌 수 있음

누적 된 차이의 부호와 운반이있는 경우 추가 비트를 운반해야합니다.

또 다른 방법은 16 진수를 간단히 추가하여 잔류 모듈로 15를 얻는 것입니다. 물론 0, 5, 10의 세 가지 허용 가능한 결과를 식별하려면 최종 논리 단계가 필요합니다.

예 70 : 4 6-> A이므로 70은 5로 나눌 수 있지만 15로 나눌 수 없습니다. 예 49 : 3 1-> 4이므로 70은 5로 나눌 수 없습니다.

컴퓨터 논리에서는 2 +/- 1의 거듭 제곱에 대한 것이 가장 구현하기 쉽지만 다른 수 기준을 사용하여 많은 분 산성 테스트를 구성 할 수 있습니다.

십진 산술에서, 내가 가장 좋아하는 것 중 하나는 잔류 모드 7에 대한 테스트입니다. 100은 7의 배수보다 2가 크므로 숫자를 쌍으로 그룹화하고 (숫자 100으로 작업) 단위에서 수백 개의 TWICE를 추가하십시오. 여기서 우리는 왼쪽에서 오른쪽으로 일합니다 ...

예 : 98 76-> 2 72-> 76이므로 9876은 7로 나눌 수 없습니다. 6 mod 7입니다. 예 : 03 45 67-> 51 67-> 1 69-> 71 1 모드 7.

물론, 이진법에서는 8 진수 (3 비트 그룹)의 합을 취하면됩니다.

죄송합니다. Verilog 전문가 였으면 좋겠습니다. 그러나이 단계에서 산술 만 할 수 있습니다. 이와 같은 많은 트릭은 Ron Doerfler의 "Dead Reckoning"을 참조하십시오.


캐나다 사촌이 특별한 알고리즘을 가지고 있는지 궁금합니다. 그들이 캐나다 페니를 금지했기 때문에 모든 가격은 가장 가까운 $ 0.05로 반올림됩니다.
richard1941

1

VHDL 인터뷰 질문으로 인해 VHDL 코드가 생성됩니다.

나는 ghdl의 저자가 17 줄의 함수로 구현을 증류시킨 Dave Tweed의 상태 전이 테이블의 구현 으로 ghdl llvm 백엔드 버그를 찾을 수있었습니다 .

type remains is (r0, r1, r2, r3, r4); -- remainder values

    function mod5 (dividend: bit_vector) return boolean is
        type remain_array is array (NBITS downto 0) of remains;
        type branch is array (remains, bit) of remains;
        constant br_table:  branch := ( r0 => ('0' => r0, '1' => r1),
                                        r1 => ('0' => r2, '1' => r3),
                                        r2 => ('0' => r4, '1' => r0),
                                        r3 => ('0' => r1, '1' => r2),
                                        r4 => ('0' => r3, '1' => r4)
                                      );
        variable  remaind:    remains := r0;
        variable tbit:        bit_vector (NBITS - 1 downto 0) := dividend;
    begin
        for i in dividend'length - 1 downto 0 loop
            remaind := br_table(remaind,tbit(i));
        end loop;
        return remaind = r0;
end function;

관련된 테스트 사례는 매우 작아 디버깅이 쉬우 며 열거 유형의 VHDL과 호환되는 상태 이름을 사용합니다.

dave_tweed.png (디아와 함께 만든)

여기서 아이디어는 함수 (또는 27 줄의 예제 VHDL 프로그램)가 인터뷰 중에 VHDL 답변을 작성하기에 충분히 짧다는 것입니다. 지식과 기술을 모두 요구하는 인터뷰 질문을 망칠 염려가 없어도, 인터뷰 대상자는 질문이있을 때 구현을 방어해야합니다.

(llvm 백엔드 버그는 오늘 일찍 커밋 1f5df6e 에서 수정되었습니다 .)

주의해야 할 사항 중 하나는 상태 전이 테이블에서 몫 비트가 피제수에서 5를 뺄 때 나머지 값이 더 낮은 상태 (또는 r4에 대한 두 전이) 로의 전환으로 표시되는 몫 비트가 '1'인 위치를 알려줍니다. 별도의 테이블 (또는 번거로운 레코드 유형의 테이블)로 인코딩 할 수 있습니다. 우리는 역사적으로 5 픽셀의 배수 인 수평 화면 해상도를 다루는 그래픽 하드웨어에서이 작업을 수행합니다.

그렇게하면 몫과 나머지를 생성하는 div / mod5가 제공됩니다.

library ieee;
use ieee.std_logic_1164.all;

entity divmod5 is
    generic (
        NBITS:  natural := 13 
    );
    port (
        clk:        in  std_logic;
        dividend:   in  std_logic_vector (NBITS - 1 downto 0);
        load:       in  std_logic;
        quotient:   out std_logic_vector (NBITS - 3 downto 0);
        remainder:  out std_logic_vector (2 downto 0);
        remzero:    out std_logic
    );
end entity;

architecture foo of divmod5 is
    type remains is (r0, r1, r2, r3, r4); -- remainder values
    type remain_array is array (NBITS downto 0) of remains;
    signal remaindr:    remain_array := (others => r0);
    signal dividendreg: std_logic_vector (NBITS - 1 downto 0);
    signal quot:        std_logic_vector (NBITS - 3 downto 0);
begin

parallel:
    for i in NBITS - 1 downto 0 generate
        type branch is array (remains, bit) of remains;
        -- Dave Tweeds state transition table:
        constant br_table:  branch := ( r0 => ('0' => r0, '1' => r1),
                                        r1 => ('0' => r2, '1' => r3),
                                        r2 => ('0' => r4, '1' => r0),
                                        r3 => ('0' => r1, '1' => r2),
                                        r4 => ('0' => r3, '1' => r4)
                                      );

        type qt is array (remains, bit) of std_ulogic;
    -- Generate quotient bits from Dave Tweeds state machine using q_table.
    -- A '1' when a remainder goes to a lower remainder or for both branches
    -- of r4. A '0' for all other branches.

        constant q_table:   qt :=     ( r0 => (others => '0'),
                                        r1 => (others => '0'),
                                        r2 => ('0' => '0', '1' => '1'),
                                        r3 => (others => '1'),
                                        r4 => (others => '1')
                                      );
        signal tbit:    bit;
    begin
        tbit <= to_bit(dividendreg(i));
        remaindr(i) <= br_table(remaindr(i + 1),tbit);
do_quotient:
        if i < quot'length generate   
            quot(i) <= q_table(remaindr(i + 1),tbit);
        end generate;
    end generate;

dividend_reg:
    process (clk)
    begin
        if rising_edge(clk) then
            if load = '1' then
                dividendreg <= dividend;
            end if;
        end if;
    end process;

quotient_reg:
    process (clk)
    begin
        if rising_edge (clk) then
            quotient <=  quot;
        end if;
    end process;

remainders:
    process (clk)
    begin
        if rising_edge(clk) then 
            remzero <= '0';
            case remaindr(0) is
                when r0 =>
                    remainder <= "000";
                    remzero <= '1';
                when r1 =>
                    remainder <= "001";
                when r2 =>
                    remainder <= "010";
                when r3 =>
                    remainder <= "011";
                when r4 =>
                    remainder <= "100";
            end case;
        end if;
    end process;

end architecture;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity divmod5_tb is
end entity;

architecture foo of divmod5_tb is
    constant NBITS:    integer range 0 to 13 := 8;
    signal clk:        std_logic := '0';
    signal dividend:   std_logic_vector (NBITS - 1 downto 0);
    signal load:       std_logic := '0';

    signal quotient:   std_logic_vector (NBITS - 3 downto 0);
    signal remainder:  std_logic_vector (2 downto 0);
    signal remzero:    std_logic;
    signal psample:    std_ulogic;
    signal sample:     std_ulogic;
    signal done:       boolean;
begin
DUT:
    entity work.divmod5
        generic map  (NBITS)
        port map (
            clk => clk,
            dividend => dividend,
            load => load,
            quotient => quotient,
            remainder => remainder,
            remzero => remzero
        );
CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if done'delayed(30 ns) then
            wait;
        end if;
    end process;
STIMULI:
    process
    begin
        for i in 0 to 2 ** NBITS - 1 loop
            wait for 10 ns;
            dividend <= std_logic_vector(to_unsigned(i,NBITS));
            wait for 10 ns;
            load <= '1';
            wait for 10 ns;
            load <= '0';
        end loop;
        wait for 15 ns;
        done <= true;
        wait;
    end process;

SAMPLER:
    process (clk)
    begin
        if rising_edge(clk) then
            psample <= load;
            sample <= psample after 4 ns;
        end if;
    end process;

MONITOR:
    process (sample)
        variable i:     integer;
        variable div5:  integer;
        variable rem5:  integer;
    begin
        if rising_edge (sample) then
            i := to_integer(unsigned(dividend));
            div5 := i / 5;
            assert div5 = unsigned(quotient)
                report LF & HT &
                    "i = " & integer'image(i) &
                    " div 5 expected " & integer'image(div5) & 
                    " got " & integer'image(to_integer(unsigned(quotient)))
                SEVERITY ERROR;
            rem5 := i mod 5;
            assert rem5 = unsigned(remainder)
                report LF & HT &
                    "i = " & integer'image(i) &
                    " rem 5 expected " & integer'image(rem5) & 
                    " got " & integer'image(to_integer(unsigned(remainder)))
                SEVERITY ERROR;
        end if;
    end process;

end architecture;

몫 비트를 생성하는 내부 생성 문인 generate 문으로 구현되었습니다. 나머지 배열은 상태 전이 추적을 제공합니다.

divmod5_tb.png

모든 산술 연산이 없습니다.

모든 레지스터가 모드가없는 상태에서 매개 변수를 사용하지 않고 절차에서 구현할 수도 있습니다. 그것은 인터뷰를 위해 최소한의 줄에 접근합니다.

클럭 순차 구현에는 비트 카운터 및 흐름 제어 (JK 플립 플롭 및 몇 개의 게이트)가 필요합니다.

인터뷰에서 방어해야 할 배당 규모에 따라 시간 / 복잡성 트레이드 오프가 발생합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.