Diferență între revizuiri ale paginii „Applications 11”

De la WikiLabs
Jump to navigationJump to search
 
(Nu s-a afișat o versiune intermediară efectuată de același utilizator)
Linia 1: Linia 1:
 
== Requirement ==
 
== Requirement ==
''Design, verify and implement a calculator. It adds, subtracts or multiplies an 8 bit number to/from the current content of its accumulator. It continuously display the input number (on the first two display digits) and the current content of the accumulator (on the last three digits of the display).''
+
''Design, verify and implement a calculator. It adds, subtracts or multiplies a 6 bit number to/from the current content of its accumulator. It continuously display the input number (on the first two display digits) and the current content of the accumulator (on the last three digits of the display). The accumulator's range is from 0 to 255.''
  
  
 
== Description ==
 
== Description ==
  
The heart of the calculator is the FSM. It receives commands from the push buttons (''PLUS'', ''MINUS'', ''MULTIPLY'' or ''CLEAR''), and sends control signals to the datapath. Apart from the FSM there are 6 registers, one for storing the result (the '''accumulator'''), and one for each of the digits used for display. The inputs shown in red are the control signals generated by the FSM. The blocks colored in blue are sequential, clocked by the 50 MHz input clock and initialized/cleared by the common reset input. The reset is assimilated to the ''CLEAR'' command.   
+
The heart of the calculator is the CTRL block. It receives commands from the push buttons (''PLUS'', ''MINUS'', ''MULTIPLY'' or ''CLEAR''), and sends control signals to the datapath. Apart from CTRL there are 6 registers, one for storing the result (the '''accumulator'''), and one for each of the digits used for display. The inputs shown in red are the control signals generated by the CTRL. The blocks colored in blue are sequential, clocked by the 50 MHz input clock and initialized/cleared by the common reset input. The reset is assimilated to the ''CLEAR'' command.   
  
 
[[Fișier: calc.png]]
 
[[Fișier: calc.png]]
Linia 17: Linia 17:
 
* For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number.
 
* For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number.
 
* For the ROM module see Exercise 1 from Applications 8, or Applications 10
 
* For the ROM module see Exercise 1 from Applications 8, or Applications 10
  The inputs '''bmul''', '''bsub''' and '''badd''' from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the FSM design:
+
  The inputs '''bmul''', '''bsub''' and '''badd''' from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the design of CTRL:
 
<syntaxhighlight lang = "verilog">
 
<syntaxhighlight lang = "verilog">
 
reg  button_d; // delayed button input
 
reg  button_d; // delayed button input
Linia 45: Linia 45:
 
* If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block:
 
* If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block:
  
 +
<syntaxhighlight lang = "verilog">
 
assign lda = badd_p | bsub_p | bmult_p;
 
assign lda = badd_p | bsub_p | bmult_p;
 
assign selfunc = {badd_p,bsub_p,bmult_p};
 
assign selfunc = {badd_p,bsub_p,bmult_p};
 +
</syntaxhighlight>
  
 
* selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable.
 
* selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable.
Linia 62: Linia 64:
 
     endcase
 
     endcase
 
end
 
end
 +
</syntaxhighlight>
 +
 +
* The multiplexers may be described inside the top module with continuous assignments:
 +
<syntaxhighlight lang = "verilog">
 +
assign w2 = sel ? w1 : w0;
 
</syntaxhighlight>
 
</syntaxhighlight>

Versiunea curentă din 23 mai 2019 05:44

Requirement

Design, verify and implement a calculator. It adds, subtracts or multiplies a 6 bit number to/from the current content of its accumulator. It continuously display the input number (on the first two display digits) and the current content of the accumulator (on the last three digits of the display). The accumulator's range is from 0 to 255.


Description

The heart of the calculator is the CTRL block. It receives commands from the push buttons (PLUS, MINUS, MULTIPLY or CLEAR), and sends control signals to the datapath. Apart from CTRL there are 6 registers, one for storing the result (the accumulator), and one for each of the digits used for display. The inputs shown in red are the control signals generated by the CTRL. The blocks colored in blue are sequential, clocked by the 50 MHz input clock and initialized/cleared by the common reset input. The reset is assimilated to the CLEAR command.

Calc.png

The output display configuration is stored in 5 registers which are updated cyclically, with a rate of around 100 Hz. In order to use one BCD converter and one BCD-to-segment converter, the input and accumulator values, and their digits are multiplexed digit by digit. A simple solution may be based on a counter from which 3 bits are used to generate the required control signals, as in the figure below:

Appl11 mux wave.png

Design hints

  • For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number.
  • For the ROM module see Exercise 1 from Applications 8, or Applications 10
The inputs bmul, bsub and badd from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the design of CTRL:
reg  button_d; // delayed button input
wire button_p; // one clock cycle pulse
always @(posedge clk)
    button_d = button;
assign button_p = button & ~button_d; // one clock cycle pulse generated after the push button was released
  • The accumulator and the FUNC block that computes its next value may be combined in a single always process:
reg [7:0] accumulator;
always @(posedge clk) begin
    if(~rst)
        accumulator <= 0;
    else if(lda) begin
        case(selfunc)
        ADD: accumulator <= accumulator + din;
        ....
        endcase
    end
    else
        accumulator <= accumulator;
end
  • If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block:
assign lda = badd_p | bsub_p | bmult_p;
assign selfunc = {badd_p,bsub_p,bmult_p};
  • selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable.
  • To control the display update a simple counter may be used:
reg [31:0] cnt;
assign selnr  = cnt[20];
assign seldig = cnt[19:18];
always @(posedge clk) begin
    case(cnt[20:18])
        3'b000: dig0 <= romdout;
        3'b001: dig1 <= romdout;
        ....
    endcase
end
  • The multiplexers may be described inside the top module with continuous assignments:
assign w2 = sel ? w1 : w0;