如何使用汇编代码访问开关的输入

时间:2019-05-19 18:50:05

标签: assembly mips hardware processor

我正在做学校作业,这是一个在FPGA板上的LED上显示蛇形图案的项目,我们必须完成MIPS处理器的代码(硬件部分)和汇编代码(软件部分)。
该项目的一部分是添加一个开关,该开关将控制蛇的运动方向。例如,如果开关为0,则蛇向前移动,而当开关为1时,蛇向后移动。

该指南说:'这更具挑战性,因为在我们的MIPS处理器中可以执行的指令数量有限。您还需要修改顶层层次结构以添加寄存器以传输此新的值开关。'

###   I/O addresses Reference
###  compatible to the compact modelling
###  0x00007FF0   LED output

#0x001e8484 original delay
.data
pattern: .word 0x00200000,0x00004000,0x00000080,0x00000001,0x00000002,0x00000004,0x00000008,0x00000400,0x00020000,0x01000000,0x02000000,0x04000000
loopcnt: .word 1200000

.text
   lw $t3, loopcnt    # initialize a  large loopcounter (so that the snake does not crawl SUPERFAST)
   addi $t5,$0,48       # initialize the length of the display pattern (in bytes)

restart:   
   addi $t4,$0,0

forward:
   beq $t5,$t4, restart
   lw $t0,0($t4)
   sw  $t0, 0x7ff0($0) # send the value to the display

   addi $t4, $t4, 4 # increment to the next address
   addi $t2, $0, 0 # clear $t2 counter
   lw $t6, 0x7ff4($0)
   addi $t6, $t6, 1

wait:
   beq $t2,$t3,forward  
   add  $t2, $t2, $t6     # increment counter
   j wait

以上是到目前为止的汇编代码,我的想法是,当switch为1(向后蛇动)时,我们递减到先前的地址,即addi $ t4,$ t4,-4。
但是我很困惑如何访问switch的值,正是指南所说的“您还需要修改顶层层次结构,以添加一个寄存器来传递此值。新的开关。顶部模块(top.v文件)需要哪些其他硬件/体系结构更改才能实现此“ 我不知道该怎么做,该寄存器应该连接到哪一部分,然后可以在汇编代码中访问它?

module top(
           input            FPGACLK,
           // TODO PART II for Lab 8           
           // add input port to read the switch value for speed control of the snake
           input [1:0]      SWITCHES,
           input            RESET,
           output [6:0]     LED,
           output reg [3:0] AN
           );

   // Define internal signals
   wire                     CLK;                 // The output of the clock divider 10 MHz Clock

   // MIPS interface
   wire [31:0]              IOWriteData;
   wire [3:0]               IOAddr;
   wire                     IOWriteEn;
   wire [31:0]              IOReadData;
   // Signals for driving the LED, note all are 'reg'
   reg [27:0]               DispReg;        // Register that holds the number
   reg [6:0]                DispDigit;      // Present 4bit value to drive the 
   reg [15:0]               DispCount;     // Simple counter to go through all options
   // The counter is large to allow enough time
   // for each LED to fully light up. 
   // we could probably increase it a bit further

   // Signals for composing the input
   wire [1:0]               IOin;           // output of the multiplexer


   // Instantiate an internal clock divider that will 
   // take the 50 MHz FPGA clock and divide it by 5 so that
   // We will have a simple 10 MHz clock internally
   clockdiv ClockDiv (
                      .clk(FPGACLK), 
                      .rst(RESET), 
                      .clk_en(CLK)
                      );

   // Counter for the display refresh
   always @ (posedge CLK, posedge RESET)
     if (RESET) DispCount = 0;
     else       DispCount = DispCount + 1;

   // Simple Way to determine the outputs, use a combinational process
   // Use the MSB of the Disp count so that each digit lights up for
   // 1.6ms  == 65536/4 * 100ns
   always @ ( * )  // combinational process
     begin
        case (DispCount[15:14])
          2'b00:   begin AN = 4'b1110; DispDigit = DispReg[6:0];  end   // LSB
          2'b01:   begin AN = 4'b1101; DispDigit = DispReg[13:7];  end   // 2nd digit
          2'b10:   begin AN = 4'b1011; DispDigit = DispReg[20:14]; end   // 3rd digit
          2'b11:   begin AN = 4'b0111; DispDigit = DispReg[27:21];end   // MSB, default
        endcase  
     end

   // Instantiate the 7segment Display Driver
   // led_driver sevendriver ( .S(DispDigit), .D(LED) );  // Instantiate the driver
   assign LED = ~DispDigit;


   // TODO for Part II of Lab 8
   // The speed of the snake must be read as input and sent to the MIPS processor.
   // Create the 32 bit IOReadData based on IOAddr value. Remember IOAddr is a 4-bit
   // value.

   //assign IOReadData = (IOAddr == 1'h4)? {{30{1'b0}}, SWITCHES} : 32'h0;
   // For some reason the above check never succeeds even though it should.
   // Therefore we just assign it directly always, which works fine in our specific case.
   assign IOReadData = {{30{1'b0}}, SWITCHES};

   // Register to save the 28-bit Value
   always @ (posedge CLK, posedge RESET)
     if      (RESET)     DispReg = 28'h0;          // Funny default value 
     else if (IOWriteEn)                              // Only when IOWrite 
       DispReg = IOWriteData[27:0];           // only the lower half


   // Instantiate the processor
   MIPS processor (
                   .CLK(CLK), 
                   .RESET(RESET), 
                   .IOWriteData(IOWriteData), 
                   .IOAddr(IOAddr), 
                   .IOWriteEn(IOWriteEn), 
                   .IOReadData(IOReadData)
                   );



endmodule

0 个答案:

没有答案