2021年6月25日 星期五

DE2-115 Left/right arithmetic shift by 1 or 8

DE2-115  Left/right arithmetic shift by 1 or 8

建立一個具有同步置數的16位元算術移位Register。 Shifter可以向左和向右移位1或8位的位置(按不同的數字進行選擇)。
算術右移是將移位寄存器中數字(q[15])的符號位移位,而不是邏輯右移所做的零。另一種考慮算術右移的方法是,它假設移動的數是有符號的,並且保留了符號,所以算術右移將有符號的數除以2的冪。


邏輯左移和算術左移之間沒有區別。


load:data[15:0]置入移位寄存器而不是移位。
ena:選擇是否移位。
amount:選擇移位方向和移位改變多少:
amount操作
2’b00左移1位 
2’b01左移8位
2’b10右移1位  (注意Sign bit)
2’b11右移8位 (注意Sign bit)

//Filename: Shift_1_8.v
module Shift_1_8 (
 input  CLOCK_50,
 input  [17:0] SW,
 input  [3:0]  KEY,
 output [15:0] LEDR
);
wire  clk_1;
// 1Hz clock
//divn # (.WIDTH(26), .N(50_000000))
divn # (.WIDTH(26), .N(15_000000))
u0 (  .clk(CLOCK_50), .rst_n(KEY[0]), .o_clk(clk_1));
top_module u1( 
 .clk(clk_1), 
 .load(KEY[1]),
 .ena(KEY[2]),
 .amount(SW[17:16]),
 .data(SW[15:0]),
 .q(LEDR[15:0]) // output  

 ); 
 
endmodule

//================================
module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [15:0] data,
    output reg [15:0] q); 
    
       always @(posedge clk)
        begin
            if (!load)
                q <= data;
            else if (ena)
                begin
                    case (amount)
                        2'b00 : q <= {q[14:0],1'b0};  //邏輯左移
                        2'b01 : q <= {q[7:0],8'b0};   //邏輯左移
                        2'b10 : q <= {q[15],q[15:1]}; //算術右移
                        2'b11 : q <= {{8{q[15]}},q[15:8]};//算術右移
                    endcase
                end
         end   

endmodule

//================================
/*
Filename  : divn.v
*/
module divn  (
  input  clk,
  input  rst_n,
  output o_clk
);

parameter WIDTH = 3;
parameter N  = 6;

reg [WIDTH-1:0] cnt_p;
reg [WIDTH-1:0] cnt_n;
reg  clk_p;
reg  clk_n;

assign o_clk = (N == 1) ? clk : (N[0]) ? (clk_p | clk_n) : (clk_p);

always@(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_p <= 0;
else if (cnt_p == (N-1))
cnt_p <= 0;
else
cnt_p <= cnt_p + 1;
end

always@(posedge clk or negedge rst_n) begin
if (!rst_n)
clk_p <= 1;
else if (cnt_p < (N>>1))
clk_p = 1;
else
clk_p = 0;
end

always@(negedge clk or negedge rst_n) begin
if (!rst_n)
cnt_n <= 0;
else if (cnt_n == (N-1))
cnt_n <= 0;
else
cnt_n <= cnt_n + 1;
end

always@(negedge clk or negedge rst_n) begin
if (!rst_n)
clk_n <= 1;
else if (cnt_n < (N>>1))
clk_n = 1;
else
clk_n = 0;
end

endmodule
//================================

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...