CSE 260 Digital Computers: Organization and Logical Design Exam 2 Solutions Jon Turner 1. (10 points). The table at right shows a table with 5 rows and three columns with each column having a heading. Write a VHDL definition of a record type that would be suitable for representing one row of such a table. Assume that the xpos and ypos values are eight bit logic vectors and that the color value is a three bit logic vector. Use the column headings as the field names. type rowtype is record xpos, ypos: std_logic_vector(7 downto 0); color: std_logic_vector(2 downto 0); end record; xpos ypos color x20 x31 4 x66 x11 3 x47 x16 7 x18 x25 5 x12 x44 1 Write a second VHDL type definition and a declaration for a signal called table that could be used to represent the table at right (you are not required to initialize table). type tabletype is array(0 to 4) of rowtype; signal table: tabletype; The VHDL function shown below returns a memory address associated with a given pair of xpos and ypos values. Let displaybuf be a VHDL array that represents a display buffer, in which each word is three bits wide. Write a VHDL assignment statement that uses the function to change the value of the word in displaybuf associated with table(3).xpos and table(3).ypos to table(3).color. function dbadr(x, y: in std_logic_vector(7 downto 0)) returns std_logic_vector(15 downto 0) is begin return x & y; end dbadr; displaybuf(int(dbadr(table(3).xpos,table(3).ypos))) <= table(3).color; - 1 -
2. (10 points) The testbench below does an exhaustive test of a combinational circuit that compares a pair of 2 digit BCD values and outputs the larger of the two. Show how you can add assertions to the testbench to verify that the results are correct. entity testbcdmax end testbcdmax; architecture a1 of testbcdmax begin subtype bcddigit is std_logic_vector(3 downto 0); type bcdnum is array(natural range <>) of bcddigit; component bcdmax port( x, y: in bcdnum(1 downto 0); z out bcdnum(1 downto 0)); end component signal x, y, z: bcdnum(1 downto 0); begin bcdm: bcdmax port map(x,y,z); process begin for x1 = 0 to 9 loop for x0 = 0 to 9 loop x(1) <= conv_std_logic_vector(x1,4); x(0) <= conv_std_logic_vector(x0,4); for y1 = 0 to 9 loop for y0 = 0 to 9 loop y(1) <= conv_std_logic_vector(y1,4); y(0) <= conv_std_logic_vector(y0,4); wait for 20 ns; if x = y then assert (z = x); elseif x1 > y1 or (x1 = y1 and x0 > y0) then assert (z = x); else assert (z = y); end loop; end loop; end loop; end loop; assert false report simulation ended normally severity error; end process; end a1; - 2 -
3. (10 points) The VHDL module defined below implements a circuit that counts the number of times that input X becomes larger than input Y. So for example, with the sequence of input pairs (X,Y) = (7,5), (4,6), (8,6), (9,13), (15, 2) the final value of the output, nupcrossings should be 2. Complete the schematic at the bottom of the page so it implements this circuit; add only simple gates and wires. entity upcross is Port ( clk, reset: in std_logic; X, Y: in std_logic_vector(3 downto 0); nupcrossings: out std_logic_vector(7 downto 0); end upcross; architecture a1 of upcross is signal count: std_logic_vector(7 downto 0); signal prevcompare: std_logic; begin process (clk) begin if rising_edge(clk) then if reset = '1' then count <= (count range => 0 ); prevcompare <= 1 ; else if X > Y then prevcompare <= 1 ; else prevcompare <= 0 ; if prevcompare = 0 and X > Y then count <= count + 1; end process; nupcrossings <= count; end a1; - 3 -
4. (20 points) In this problem you are to write a VHDL architecture for a pulsedifferencer circuit, with the interface defined by the entity declaration shown below. entity pulsedifferencer is port( clk, reset: in std_logic; up, down: in std_logic; diff: out word); end entity pulsedifferencer; When the up input goes low, after having been high for m clock ticks, the diff output should increase by m. Similarly, when the down input goes low, after having been high for n clock ticks, the diff output should decrease by n. If both go low at the same time, diff should increase by (m n). The required behavior is illustrated in the timing diagram below. Note that diff changes only when one or both of the inputs drops and it changes on the first rising clock edge following the drop in the input. Write a complete VHDL architecture that implements this circuit. You may assume that up and down are low immediately after reset and that the value of diff will never be larger 200. Your VHDL should be complete and syntactically correct. Include comments as needed to make your code easy to understand. You may continue onto the next page. - 4 -
architecture a1 of pulsedifferencer signal prevup, prevdown: std_logic; signal ucnt, dcnt, count: std_logic_vector(7 downto 0); begin process (clk) begin if rising_edge(clk) then prevup <= up; prevdown <= down; if reset = 1 then count <= (others => 0 ); else -- upcnt is number of ticks up has been high if up = 0 then ucnt <= (others => 0 ); else ucnt <= ucnt + 1; -- downcnt is number of ticks down has been high if down = 0 then dcnt <= (others => 0 ); else dcnt <= dcnt + 1; if up < prevup and down < prevdown then count <= count + (ucnt - dcnt); elsif up < prevup then count <= count + ucnt; elsif down < prevdown then count <= count - dcnt; end process; diff <= count; end a1; - 5 -
5. (10 points). The Washu-2 processor simulation shown below has several places that have been replaced with blank spaces labeled with letters. In the spaces below, fill in the values that should appear where the blanks are. A. 0007 B. 0010 C. 0001 D. 8011 E. 0011 The instruction set for the processor appears below. 0000 halt 0001 negate 01xx branch 02xx branch if zero 03xx branch if positive 04xx branch if negative 05xx indirect branch 1xxx 2xxx 3xxx 5xxx 6xxx 8xxx cxxx immediate load direct load indirect load direct store indirect store add and - 6 -
6. (15 points) Write a subroutine for the WashU-2 that takes two arguments x and y and returns max(x,y). The calling program should write the arguments and the return address in locations 1000, 1001 and 1002 before calling the subroutine. The first instruction of the subroutine is at location 1003. Your subroutine should return the result in the ACC. Include enough comments to make it clear what your code is doing. 1000 -- argument x 1001 -- argument y 1002 -- return address 1003 2001 ACC=y -- ACC=x-y 1004 0001 ACC=-y 1005 8000 ACC=x-y 1006 0403 if x<y jump ahead 3 -- if ACC>=0 return x 1007 2000 ACC=x 1008 05fa return x 1009 2001 ACC=y -- else return y 100a 05f8 return y - 7 -
7. (10 points) The simulation output shown below shows the WashU-2 processor pausing during the execution of a program. There are three specific reasons that the console causes the processor to pause. Name these three reasons. The console may pause the processor because the single-step button was pressed. The console may pause the processor in order to read from a memory location in order to update the value of snoopdata. The console may pause the processor in order to write the value in snoopdata to a memory location. For which of these three reasons did the processor pause in the simulation shown above. Explain how you can tell. It this case the processor paused to write a value to memory. We can tell because just before it leaves the pause state, the mem_en signal goes high and the mem_rw signal goes low. - 8 -